我有一个专门用于特定类型的函数模板。在某些情况下,我无法调用专用版本。为了显示
struct Base {};
struct Derived : public Base {};
template <typename VALTYPE> void FooInternal(VALTYPE&)
{
std::cout << L"FooInternal template";
}
template<> void FooInternal(Base&)
{
std::cout << L"FooInternal SPECIAL";
}
现在,如果我构造一个“Base”或“Derived”的实例并调用“FooInternal”,所有的工作都如我所料
int _tmain(int argc, _TCHAR* argv[])
{
int x = 7;
FooInternal(x); // Calls FooInternal<VALTYPE>() template
Base b;
FooIntenral(b); // Calls FooInternal<Base>() specialization
Derived d;
FooInternal(d); // Calls FooInternal<Base>() specialization
return 0;
}
这个的输出是
FooInternal template
FooInternal SPECIAL
FooInternal SPECIAL
}
但是假设我在这两者之间有一个调用 FooInternal 的中间函数模板。在这种情况下,派生类型的模板解析似乎一路失败
// Intermediate template. Just calls FooInternal.
template<typename VALTYPE>
void Foo(VALTYPE& val)
{
FooInternal<VALTYPE>(val);
}
// Now repeat the same 3 calls and see what happens with Derived...
int _tmain(int argc, _TCHAR* argv[])
{
int x = 7;
Foo(x); // Calls FooInternal<VALTYPE>() template
Base b;
Foo(b); // Calls FooInternal<Base>() specialization
Derived d;
Foo(d); // Calls FooInternal<VALTYPE>() template!!!
return 0;
}
这个程序的输出是
FooInternal template
FooInternal SPECIAL
FooInternal template
我不明白为什么——在第三次调用中,“Foo”不会像直接调用时那样调用 FooInternal 的专用版本。在这种情况下,编译器不应该理解它是从“Base”派生的吗?我在这里缺少什么规则?
如果这很重要,我正在使用 Microsoft Visual Studio 2012 Update 3。
-乔