c++ - Strange error with a templated operator overload -
when compile following snippet, compiler error clang, not g++/msvc:
#include <string> template<typename t> struct const { explicit const(t val) : value(val) {} t value; }; template<typename t> struct var { explicit var(const std::string &n) : name(n) {} std::string name; }; template<typename l, typename r> struct greater { greater(l lhs, r rhs) : left(lhs), right(rhs) {} l left; r right; }; template<typename l> greater<l, const<int> > operator > (l lhs, int rhs) { return greater<l, const<int> >(lhs, const<int>(rhs)); } template<typename r> greater<const<int>, r> operator > (int lhs, r rhs) { return greater<const<int>, r>(const<int>(lhs), rhs); } var<double> d("d"); int main() { d > 10; return 0; }
the error reported following:
error: overloaded 'operator>' must have @ least 1 parameter of class or enumeration type greater<const<int>, r> operator > (int lhs, r rhs) { ^ ./val.h:31:24: note: in instantiation of function template specialization 'operator><int>' requested here greater<const<int>, r> operator > (int lhs, r rhs) { ^ 1 error generated.
which operator function not used. if, instead, write 10 > d instead of d > 10, same error other operator > function. above compiles fine under gcc 4.4.6 , vs2012. mistake ?
thank you.
clang right: operator overloading requires @ least 1 class or enum type parameter, otherwise program ill-formed (13.5/1). see why error appears, have parse more standard legalese.
recall holy trinity of name lookup, argument deduction , overload resolution. first step finds 2 overloaded operator>
. second step deduces template arguments each version. might think second overload fall victim sfinae rule (14.8.2), first survives third step. however, there no substition failure (as in e.g. missing nested typedef), illegal construct (see earlier mentioned 13.5/1). renders program ill-formed (14.3/6)
6 if use of template-argument gives rise ill-formed construct in instantiation of template specialization, program ill-formed.
in 14.8.3 mentioned check on deduced arguments happens before overload resolution, preferred operator has no chance of being selected.
as c++03 work-around, define 2 friend non-template operator>
inside var<t>
class template. these injected surrounding (global, in example) namespace non-template functions 1 class type parameter, above error should not occur.
Comments
Post a Comment