Re: why std::vector<T>&& is not a universal reference?
Am 10.10.2012 10:50, schrieb rogeeva@googlemail.com:
I have another related question. Let's say all my templates are in
namespace myns and I want to implement operator+ for them following
above guideline:
namespace myns {
... // my types here
template<typename T1,typename T2>
my_result_type<T1,T2>
operator+( T1&& arg1, T2&& arg2 )
{
...
}
} // namespace myns
An intention here is to implement an operator+ for types in my
namespace. Now the question is: do I really need to add enable_if
constrain (constraining by some trait identifying my types) or I can
rely on ADL to do his for me (let's also assume I never intend to use
"using namespace myns" in the code anywhere)?
I still consider this as a dangerous situation. To exemplify this
consider that your library is used in another library or program. To do
this I need to give some of your mentioned types in your library
concrete names, e.g.
namespace myns {
template<class T>
struct type_1 {};
template<class T>
struct type_2 {};
/* ... */
template<typename T1,typename T2>
my_result_type<T1,T2>
operator+(T1&& arg1, T2&& arg2);
} // namespace myns
This different library has - lets say - its own namespace otherns and
contains also algebra function, but for different types. To allow a
smooth integration with your library it provides some mixed algebra
functions with your types, e.g.
namespace otherns {
template<class T>
struct type_a { /**/ };
template<class T>
struct type_b {};
/* ... */
// Own algebra:
template<typename T1,typename T2>
her_result_type<T1,T2>
operator+(const type_a<T1>& arg1, const type_b<T2>& arg2);
// Mixed algebra:
template<typename T1,typename T2>
her_result_type<T1,T2>
operator+(const type_a<T1>& arg1, const myns::type_2<T2>& arg2);
template<typename T1,typename T2>
her_result_type<T1,T2>
operator+(const myns::type_1<T1>& arg1, const type_b<T2>& arg2);
}
Now consider this program that performs a seemingly very intuitive
operation:
int main() {
otherns::type_a<int> i1;
myns::type_2<int> i2;
auto res = i1 + i2;
}
The programmer writing this code expected that this operator would have
selected the very specific mixed operator signature
template<typename T1,typename T2>
otherns::her_result_type<T1,T2>
otherns::operator+(const otherns::type_a<T1>& arg1, const
myns::type_2<T2>& arg2);
This won't happen: Despite the fact that otherns didn't provide much too
broad template overloads, the "catch-all" perfect forwarding overload
template<typename T1,typename T2>
my_result_type<T1,T2>
operator+(T1&& arg1, T2&& arg2);
will still be selected, because it is a better match (The arguments are
not const). The cause of the problem is the much too broad acceptance of
arguments by the unconstrained overload from namespace myns.
Note also that if otherns would *also* have provided the same kind of
unconstrained perfect-forwarding operator+, the program would now be
ill-formed, because none of these were better than the other.
So unless you consider not to share your code with other programmers, I
strongly recommend to constrain such an operator to prevent programs
that either break other peoples code or - even worse - are silently
accepted and do enter a completely unexpected code path by user code.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]