gpt4 book ai didi

c++ - 从另一个模板对象调用模板方法时出现奇怪的编译行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:48 26 4
gpt4 key购买 nike

有人可以解释为什么以下 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 支持进行编译)。

最后一个版本没问题,但我不明白为什么使用临时变量存储引用可以解决问题。

我很想知道为什么其他三个无效。

谢谢

最佳答案

你必须使用 template作为:

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.foo1 ,而是用于传递模板参数 1到函数模板,你需要使用 template关键字。

关于c++ - 从另一个模板对象调用模板方法时出现奇怪的编译行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13660958/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com