c – 从另一个模板对象调用模板方法时出现奇怪的编译行为
有人可以解释为什么以下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支持编译). 最后一个版本工作正常,但我不明白为什么使用临时变量存储引用解决了问题. 我很想知道为什么其他三个无效. 谢谢 解决方法
你必须使用模板:
v[0].template foo<1>(); auto &o = v[0]; o.template foo<1>(); 因为v的声明取决于模板参数,这使得v成为依赖名称. 这里template关键字告诉编译器,后面的任何内容都是模板(在你的情况下,foo确实是一个模板).如果foo不是模板,则不需要template关键字(事实上,这将是一个错误). 问题是o.foo< 1>()可以用两种方式解析/解释:一种是你期望的(函数调用),另一种方式是: (o.foo) < 1 //partially parsed 也就是说,foo是一个成员数据(不是函数),你将它与1进行比较.所以要告诉编译器<不用于将o.foo与1进行比较,而是用于将模板参数1传递给函数模板,您需要使用template关键字. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |