【发布时间】:2012-10-02 14:59:58
【问题描述】:
我从来没有很好地解释模板参数推导是如何工作的,所以我不确定如何解释我在下面看到的行为:
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<'
如果您将 Derived 中的 2 个 Base<T>s 更改为 Base<int>,它将编译。如果您将对Bar() 的调用更改为Base<T>::template Bar<false>(5);,它也会编译。
我看到的一个解释是编译器不知道 Bar 是一个模板,大概是因为它不知道 Base 是什么,直到声明了 Derived 的特化。但是一旦编译器开始为Foo() 生成代码,Base<T> 就已经定义好了,Bar 的类型就可以确定了。是什么导致编译器假定符号 Bar 不是 模板,而是尝试应用 operator<()?
我认为它与在编译过程中评估模板时的规则有关 - 我想我正在寻找的是对这个过程的一个很好的全面解释,这样下次我遇到类似的代码时下面,我可以在没有堆栈溢出的好人帮助的情况下推断出答案。
请注意,我使用 g++ 4.7 进行编译,支持 c++x11。
【问题讨论】:
-
我认为我的常见问题解答并没有解释为什么在实例化时不只解析模板(如果我理解正确,这就是这里所问的)。我的常见问题解答认为编译器在定义模板时会尽早解析模板。所以我不知道欺骗链接是否真的没问题。
-
刚读完,虽然不是我要找的唯一东西,但仍然是非常好的信息!
标签: c++ templates static c++11