我从来没有很好地解释模板参数推导如何真正起作用,所以我不确定如何解释我在下面看到的行为:
template<typename T>
struct Base
{
protected:
template<bool aBool = true>
static void Bar(int)
{
}
};
template<typename T>
class Derived : public Base<T>
{
public:
void Foo() { Base<T>::Bar<false>(5); }
};
int main()
{
Derived<int> v;
v.Foo();
return 0;
}
此代码不会构建,并给出错误:
main.cpp: In instantiation of 'void Derived<T>::Foo() [with T = int]':
main.cpp:25:8: required from here main.cpp:19:15: error: invalid
operands of types '<unresolved overloaded function type>' and 'bool'
to binary 'operator<'
如果将Base<T>
Derived 中的 2 更改为Base<int>
,它会编译。如果将调用更改Bar()
为Base<T>::template Bar<false>(5);
,它也会编译。
我看到的一个解释是编译器不知道 Bar 是一个模板,大概是因为它不知道 Base 是什么,直到声明了 Derived 的特化。但是一旦编译器开始为 , 生成代码Foo()
,Base<T>
就已经定义了,并且Bar
可以确定 的类型。是什么导致编译器假定符号Bar
不是模板,并尝试应用operator<()
?
我认为它与在编译过程中评估模板时的规则有关 - 我想我正在寻找的是对这个过程的一个很好的全面解释,这样下次我遇到如下代码时,我可以在没有堆栈溢出的好人帮助的情况下推断出答案。
注意我使用 g++ 4.7 编译,支持 c++x11。