gpt4 book ai didi

c++ - 模板类中的模板友元函数

转载 作者:行者123 更新时间:2023-12-02 10:22:41 25 4
gpt4 key购买 nike

实现 template friend function 的问题在 template class 内过去已经讨论过,似乎是an unresolved issue in the standard具有不同编译器的不同行为。

检查 gcc 和 clang 的最新可用版本,似乎已做出决定,要求实现 template friend function成为 template class .

以下代码在使用 -std=c++2a 编译时被最新版本的 gcc 和 clang(gcc x86-64 9.2.0 和 clang x86-64 9.0.0)拒绝。过去的 clang 版本可以接受(例如 clang x86-64 7.0.0)。

template<long Num>
struct A {
template<long Num1, long Num2>
friend int foo(A<Num1> a1, A<Num2> a2) {
return 1;
}
// the compilation error occurs only with a template friend function
// and only if *implemented inside* a template class
};

int main() {
A<1> a1;
A<2> a2; // commenting this line removes the error
}

两个编译器都提示重新定义 foo:
<source>:4:16: error: redefinition of 'foo'    
friend int foo(A<Num1> a1, A<Num2> a2) {
^
<source>:11:10: note: in instantiation of template class 'A<2>' requested here
A<2> a2;
^

是否有关于该主题的新官方决议,或者它只是最新的编译器时尚?

https://godbolt.org/z/ySrVe3

最佳答案

我从 CWG 2174 的决议中找出了相关的措辞。它在 C++17 的 [temp.inst]/2 中:

However, for the purpose of determining whether an instantiated redeclaration is valid according to [basic.def.odr] and [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition.



因此,编译器需要将定义的实际实例化推迟到 foo 的定义的位置。需要存在(在你的代码中,没有这样的点,所以 foo 没有被实例化),但即使定义没有被实例化,编译器仍然需要在同一个翻译单元中诊断多个定义,就好像每次实例化声明时都会实例化定义。

在我看来,这条规则使得使用友元函数变得不必要地困难,而没有明显的好处,如果在一个类模板中定义的友元函数的多个定义,在同一个 TU 中实例化,被认为是一个单一的,那就更好了定义。也许,如果我有更多的时间,我会建议对标准进行这样的更改。 (是的,我是说我没有时间,所以如果其他人想这样做,请继续,不要担心重复努力。)

除非进行这样的更改,否则您似乎确实需要在类模板之外定义友元函数。

关于c++ - 模板类中的模板友元函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59415978/

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