c++ - Difference between "explicit" and "implicit" invocation of operator () -


is there clause in standard describing following difference between ways call operator () base classes?

#include <iostream> #include <type_traits>  #include <cstdlib> #include <cassert>  template< typename visitor, typename ...visitors > struct composite_visitor     : std::decay_t< visitor >     , composite_visitor< visitors... > {      //using std::decay_t< visitor >::operator ();     //using composite_visitor< visitors... >::operator ();      composite_visitor(visitor && _visitor, visitors &&... _visitors)         : std::decay_t< visitor >(std::forward< visitor >(_visitor))         , composite_visitor< visitors... >{std::forward< visitors >(_visitors)...}     { ; }  };  template< typename visitor > struct composite_visitor< visitor >     : std::decay_t< visitor > {      //using std::decay_t< visitor >::operator ();      composite_visitor(visitor && _visitor)         : std::decay_t< visitor >(std::forward< visitor >(_visitor))     { ; }  };  template< typename visitor, typename ...visitors > composite_visitor< visitor, visitors... > compose_visitors(visitor && _visitor, visitors &&... _visitors) {     return {std::forward< visitor >(_visitor), std::forward< visitors >(_visitors)...}; }  int main() {     struct {};     struct b {}; #if 1     struct { int operator () (a) { return 1; } } x;     struct { int operator () (b) { return 2; } } y;     auto xy = compose_visitors(x, y); #else     auto xy = compose_visitors([] (a) { return 1; }, [] (b) { return 2; }); #endif     // "implicit":     assert(xy(a{}) == 1);     assert(xy(b{}) == 2);     // "explicit":     assert(xy.operator () (a{}) == 1); // error: member 'operator()' found in multiple base classes of different types     assert(xy.operator () (b{}) == 2);     return exit_success; } 

"implicit" invocation compiles fine, not "explicit". why so?

compose_visitors combine arguments single class means of construction of class derived of them.

uncommenting using derectives removes hard error. clear.

the behaviour identical lambda functions , functors.

compiler clang 3.6.

the "implicit" invocation ill-formed. in fact, gcc rejects it, seems bug in clang.

the standard (n4140, [over.call]/1) says that

a call x(arg1,...) interpreted x.operator()(arg1, ...) class object x of type t if t::operator()(t1, t2, t3) exists , if operator selected best match function overload resolution mechanism (13.3.3).

so 2 invocations must behave identically.

update: known issue in clang.


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -