Rol*_*lie 5 c++ static templates c++11
我从来没有得到关于模板参数推导如何真正起作用的很好的解释,所以我不确定如何解释我在下面看到的行为:
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;
}
Run Code Online (Sandbox Code Playgroud)
此代码不会构建,并给出错误:
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<'
Run Code Online (Sandbox Code Playgroud)
如果您将Base<T>Derived中的2更改为Base<int>,则编译.如果您将呼叫更改Bar()为Base<T>::template Bar<false>(5);,则它也会编译.
我看到的一个解释是,编译器不知道Bar是一个模板,可能是因为在声明Derived的特化之前它不知道Base是什么.但是一旦编译器开始生成代码Foo(),Base<T>已经定义了,并且Bar可以确定类型.是什么原因造成的编译器采用的符号Bar是不是一个模板,并尝试应用operator<()呢?
我假设它与在编译过程中评估模板的规则有关 - 我想我正在寻找的是对这个过程的一个很好的全面解释,这样下次我遇到如下代码时,我可以在没有堆栈溢出的好人的帮助下推断出答案.
注意我正在使用g ++ 4.7进行编译,支持c ++ x11.
void Foo() { Base<T>::Bar<false>(5); }
Run Code Online (Sandbox Code Playgroud)
在这种情况下Base<T>是一个从属名称。要访问从属名称的成员模板,您需要添加关键字template:
void Foo() { Base<T>::template Bar<false>(5); }
Run Code Online (Sandbox Code Playgroud)
否则Base<T>::Bar将被解析为非模板成员和<小于。
至于为什么template需要,原因是两阶段查找。该错误是在类型被替换之前的第一遍期间触发的,因此编译器不知道的定义是什么Base<T>。例如,考虑您添加了Bar具有int非模板Bar成员(例如成员int)的专门化。在替换Tinto之前Foo,编译器不知道该类型是否有专门化。
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |