1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
#include <iostream>
#include <string>
struct A
{
template < typename C = char, typename T = std::char_traits<C>, typename A = std::allocator<C> >
std::basic_string<C,T,A> bar() const { return {} ; }
};
template < typename X > auto foobar( const X& x ) // for instantiation: foobar<A>
{
return x.bar<>() ; // error: template disambiguator is required for the dependent name
// error: use 'template' keyword to treat 'bar' as a dependent template name - LLVM (excellent, understands and tells us what the problem really is)
// error: expected primary-expression before '>' token, expected primary-expression before ')' token - GNU (poor, mechanically generated dumb diagnostic)
// note: Microsoft (without the v140_clang_3_7 toolchain) chokes on the template disambiguator for dependent template names (bad, non-conforming)
}
int main()
{
A a ;
a.bar() ; // fine: bar< char, std::char_traits<char>, std::allocator<char> >
a.template bar() ; // fine: bar< char, std::char_traits<char>, std::allocator<char> >
a.bar<>() ; // fine: bar< char, std::char_traits<char>, std::allocator<char> >
a.template bar<>() ; // fine: bar< char, std::char_traits<char>, std::allocator<char> >
a.bar<char16_t>() ; // fine: bar< char16_t, std::char_traits<char16_t>, std::allocator<char16_t> >
a.template bar<wchar_t>() ; // fine: : bar< wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >
a.bar< char, std::char_traits<char>, std::allocator<char> >() ; // fine
a.template bar< char, std::char_traits<char>, std::allocator<char> >() ; // fine
foobar(a) ;
}
|