C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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关键字.

大佬总结

以上是大佬教程为你收集整理的c – 从另一个模板对象调用模板方法时出现奇怪的编译行为全部内容,希望文章能够帮你解决c – 从另一个模板对象调用模板方法时出现奇怪的编译行为所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。