如果我认为我对 C++ 一无所知,那么就是你不能通过返回类型重载函数。
那么任何人都可以解释这里发生了什么吗?
class A { public: typedef int _foo; };
class B {};
template<class T>
typename T::_foo Foo(int)
{
cout << "Foo(int)\n"; return typename T::_foo();
}
template<class T>
typename T Foo(char)
{
cout << "Foo(char)\n"; return typename T();
}
int main()
{
Foo<A>(0); // Writes "Foo(int)", as expected.
Foo<B>(0); // Writes "Foo(char), expected error unable to compile template.
return 0;
}
有两个类 A 和 B。A 定义 typedef _foo,B 没有。函数模板 Foo 有两个重载,Foo(int) 和 Foo(char)。Foo(int) 返回 T::_foo,Foo(char) 返回 T。
Foo(0) 然后被调用两次。这是 Foo(int) 的完全匹配,所以我希望 Foo<A>(0) 编译正常,而 Foo<B>(0) 编译失败,因为 B 没有定义模板中使用的 _foo 类型。
实际发生的是 Foo<B>(0) 完全忽略 Foo(int) 并实例化 Foo(char) 。但是根据重载决议的正常规则,Foo(0) 显然是 Foo(int) 的精确匹配,唯一使 Foo(char) 更可行的匹配是不应该考虑的返回类型。
要验证它是影响重载决议的返回值,只需添加以下内容:
template<class T>
void Bar(int) { typename T::_foo a; cout << "Bar(int)\n"; }
template<class T>
void Bar(char) { cout << "Bar(char)\n"; }
Bar<A>(0); // Writes "Bar(int), as expected.
//Bar<B>(0); // Error C2039: '_foo' : is not a member of 'B', as expected.
这清楚地表明,在没有返回值的情况下 Foo(int) 确实是正确的重载,并且如果模板无法解析其模板参数中使用的类型,则编译失败是正常结果。