有人可以解释为什么以下 c++ 代码没有按预期运行:
struct Object {
template< int i >
void foo(){ }
};
template<int counter>
struct Container {
Object v[counter];
void test(){
// this works as expected
Object a; a.foo<1>();
// This works as well:
Object *b = new Object(); b->foo<1>();
// now try the same thing with the array:
v[0] = Object(); // that's fine (just testing access to the array)
# if defined BUG1
v[0].foo<1>(); // compilation fails
# elif defined BUG2
(v[0]).foo<1>(); // compilation fails
# elif defined BUG3
auto &o = v[0];
o.foo<1>(); // compilation fails
# else
Object &o = v[0];
o.foo<1>(); // works
# endif
}
};
int main(){
Container<10> container;
}
上面的代码在没有标志的情况下编译得很好。如果设置了标志 BUG1 到 BUG3 中的一个,则使用 GCC 4.6 或 4.7 和 clang 3.2 编译会失败(这似乎表明它不是 GCC 错误)。
第 21 到 29 行在语义上做了完全相同的事情(即调用 Object 数组的第一个元素的方法),但只编译最后一个版本。只有当我尝试从模板对象调用模板化方法时,才会出现问题。
BUG1 只是编写调用的“正常”方式。
BUG2 是一样的,但数组访问受括号保护,以防出现优先级问题(但不应该有任何问题)。
BUG3 表明类型推断也不起作用(需要使用 c++11 支持编译)。
最后一个版本工作正常,但我不明白为什么使用临时变量来存储引用可以解决问题。
我很想知道为什么其他三个无效。
谢谢