#include //#define BOOST_RESULT_OF_USE_DECLTYPE 1 #include #include #include template struct subst_failure_if_not_int {}; template<> struct subst_failure_if_not_int { typedef int type; }; template typename subst_failure_if_not_int::type dispatch_int(int) { /* this overload is eliminated when substitution failure occurs */ std::cout << "called int version\n"; return 0; } template void dispatch_int(long) { /* this is fallback overload */ std::cout << "called default version\n"; } void test1() { dispatch_int (0); // prints "called int version" dispatch_int (0); // prints "called default version" } /* now, exactly the same approach applied to boost::fusion::invoke */ struct F { template struct result {}; template struct result { typedef int type; }; int operator()(float) { std::cout << "invoked F(float)\n"; } }; template typename boost::fusion::result_of::invoke::type try_invoke(int) { std::cout << "called invoke()-ing overload\n"; return boost::fusion::invoke(F(), Sequence()); } template void try_invoke(long) { std::cout << "called fallback overload\n"; } struct junk { int i; }; void test2() { // fails to compile under MSVC 9, // compiles and works as intended under GCC 4.6 when BOOST_RESULT_OF_USE_DECLTYPE enabled, // fails to compile under GCC 4.6 with decltype() usage disabled: try_invoke> (0); // fails to compile in all tested cases, while should be selecting fallback overload: try_invoke> (0); } int main() { test1(); test2(); }