Expression pattern - unable to customize function pattern

I tried to create some expression patterns as an answer to this question , but I get compiler errors that I cannot understand. I already got SSCCE

template<class sub_expr> class inherit2 : private sub_expr { //line 3 public: inherit2(sub_expr rhs) : sub_expr(rhs) {} template<class T> auto operator()(const T& v) const ->decltype(sub_expr::operator()(v)) //line 7 {return sub_expr::operator()(v);} }; class expression_parameter { public: template<class T> const T& operator()(const T& v) const {return v;} }; int main() { expression_parameter x; auto expr0 = x; int res0 = expr0(3); //line 20 auto expr1 = inherit2<expression_parameter>(x); //line 21 int res1 = expr1(3); //line 22 return 0; } 

When compiling with MSVC10 ++, I get this error:

 f:\code\utilities\exprtemplate\exprtemplate\sscce.cpp(22): error C2893: Failed to specialize function template ''unknown-type' inherit2<sub_expr>::operator ()(const T &) const' with [ sub_expr=expression_parameter ] With the following template arguments: 'int' 

When I compile with GCC 4.6.3:

 sscce.cpp: In instantiation of 'inherit2<expression_parameter>': sscce.cpp:21:47: instantiated from here sscce.cpp:3:7: warning: base class 'class expression_parameter' has a non-virtual destructor [-Weffc++] sscce.cpp: In function 'int main()': sscce.cpp:22:20: error: no match for call to '(inherit2<expression_parameter>) (int)' sscce.cpp:3:7: note: candidate is: sscce.cpp:7:10: note: template<class T> decltype (sub_expr:: operator()(v)) inherit2::operator()(const T&) const [with T = T, sub_expr = expression_parameter, decltype (sub_expr:: operator()(v)) = decltype (expression_parameter::operator()(v))] sscce.cpp:20:6: warning: unused variable 'res0' [-Wunused-variable] sscce.cpp:22:6: warning: unused variable 'res1' [-Wunused-variable] 

And finally, Clang 3.1

 sscce.cpp(22,12) : error: no matching function for call to object of type 'inherit2<expression_parameter>' int res1 = expr1(3); ^~~~~ sscce.cpp(7,9) : note: candidate template ignored: substitution failure [with T = int] auto operator()(const T& v) const ->decltype(sub_expr::operator()(v)) ^ 

So, in short: it seems that I was decltype wrong, but I can not figure out the right way. Can someone help me figure out what causes these errors?

+4
source share
2 answers

Some of the errors I received from GCC suggested to me that there is an ambiguous base. Namely, expression_multiply<expression_parameter, expression_parameter> has expression_parameter as a (direct) base and inherit_again<expression_parameter> , which itself has expression_parameter as the base. This means that lhs::operator() ambiguous in the scope of expression_multiply<expression_parameter, expression_parameter> (where lhs is actually expression_parameter .

Another fix is ​​required that this was needed in the returned type of operator() , as a result of which the following errors were fixed:

 // Instead of inherit_again template<int N, class sub_expr> class base : public sub_expr { public: base(sub_expr rhs): sub_expr(std::move(rhs)) {} }; template<class lhs_given, class rhs_given> class expression_multiply: private base<0, lhs_given>, private base<1, rhs_given> { typedef base<0, lhs_given> lhs; typedef base<1, rhs_given> rhs; public: expression_multiply(lhs_given l, rhs_given r):lhs(std::move(l)), rhs(std::move(r)) {} template<class T> auto operator()(const T& v) const -> decltype(this->lhs::operator()(v) * this->rhs::operator()(v)) { return lhs::operator()(v) * rhs::operator()(v); } }; 

I do not know if the compiler will correct errors with respect to these two “fixes”.

+2
source

This is a complement to the Luc solution. Using:

 decltype(std::declval<lhs>()( v ) * std::declval<rhs>()( v ) ) 

To help the compiler infer the type without much noise.

+2
source

All Articles