#include using std::cout; using std::endl; namespace tag { struct storage {}; template struct expression {}; }//namespace tag template struct tag_complexity { enum { value = 0 }; }; template struct tag_complexity > { enum { value = c }; }; struct general {}; struct shapeX {}; template struct expression : public expression::value>, general> {}; template struct expression {}; struct too : public expression {}; struct gives : public expression {}; template void foo(const expression &a) { cout << "foo reports\n " << typeid(a).name() << "\n\n"; return; } template struct subexpression; template struct subexpression > : public expression >, tag::expression::value>, shape > { subexpression(const expr_t&) {} }; template inline subexpression > bar(const expression &a) { cout << "bar reports\n " << typeid(a).name() << "\n\n"; return static_cast(a); } int main() { { too trivial; foo(trivial); foo(bar(trivial)); } { gives error; foo(error); //comment this line in order to compile /*msvc 77626-009-0000007-41564 (ide msvs 8.0.50727.762(sp050727-7600)) can not deduce 'tag' template argument hierarchy for class 'gives' looks like expression, general> ^ expression ^ gives so template arguments should obviously be deduced as*/ foo >(error); foo(bar(error)); //comment this line in order to compile foo( /*icc 11.0.066 can not match an instance of bar() with 'error' given hierarchy for 'gives' class template arguments for bar() should be deduced at least as*/ bar(error) );//foo( } return 0; }