Issue with defining non-member function templates for a class template

30 views
Skip to the first unread message

Lingxi Li

unread,
8 Oct 2015, 9:07:19 am8/10/15
to ISO C++ Standard - Discussion

Symptom:

 

Currently, in the standard library, when some functionality for a class template is impossible or unsuitable to be implemented as a member function, it is implemented as a non-member function template. For example, std::vector has the following non-member function template defined for it:

 

template <class T, class Allocator>
bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);

 

This issue is that functionality implemented in this manner is not accessible via std::reference_wrapper. For example:

 

#include <functional>
#include <iostream>
#include <vector>

int main() {
 
//std::vector<int> a, b;  // Oops.
 
int a = 0, b = 0;
 
auto refa = std::ref(a);
 
auto refb = std::ref(b);
  std
::cout << (refa < refb);
}


The program compiles fine when a and b are of type int, but does not when they are of type std::vector<int> despite the fact that std::reference_wrapper<std::vector<int>> is implicitly convertible to std::vector<int>& for which an overloaded operator< is defined.

 

Cause:

 

This phenomenon turns out to be caused by the template nature of the non-member functions. According to N4296 14.8.1 [temp.arg.explicit] para. 6

 

Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.

 

Suggested resolution:

 

Define the non-member functions inline as friends of their corresponding class template. Functions defined in this manner are non-templates, and are accessible via std::reference_wrapper. For example, the overloaded operator< for std::vector could be revised as

 

template <class T, class Allocator = allocator<T>>
class vector {
 
...
 
friend bool operator< (const vector& x, const vector& y) { ... }
};

 

Final Words:


I hope to report this as a library defect to the library working group, if it can be seen as such and has not been reported already.


Ville Voutilainen

unread,
8 Oct 2015, 9:10:55 am8/10/15
to std-dis...@isocpp.org
On 8 October 2015 at 16:07, Lingxi Li <lilin...@gmail.com> wrote:
> Suggested resolution:
> Define the non-member functions inline as friends of their corresponding
> class template. Functions defined in this manner are non-templates, and are
> Final Words:
> I hope to report this as a library defect to the library working group, if
> it can be seen as such and has not been reported already.


This is a design change, so LEWG is the right target. Write a paper targetting
LEWG instead of reporting an LWG issue.

Lingxi Li

unread,
8 Oct 2015, 9:27:36 am8/10/15
to ISO C++ Standard - Discussion
Any guidelines on reporting to LEWG? The official guide here only mentioned core language issues and library issues that are reported to CWG and LWG, respectively. Or, you take to mean this?

Daniel Krügler

unread,
8 Oct 2015, 9:33:03 am8/10/15
to std-dis...@isocpp.org
2015-10-08 15:27 GMT+02:00 Lingxi Li <lilin...@gmail.com>:
> Any guidelines on reporting to LEWG? The official guide here only mentioned
> core language issues and library issues that are reported to CWG and LWG,
> respectively. Or, you take to mean this?

Yes,

https://isocpp.org/std/submit-a-proposal

is a good starting point that describes how to write a proposal. If
you have any further questions, please contact the lwgchair via the
address published here:

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html

Thanks,

- Daniel
Reply all
Reply to author
Forward
0 new messages