gpt4 book ai didi

c++ - friend 、私有(private)函数、模板别名和 decltype ......在拒绝这个方面是正确的吗?

转载 作者:行者123 更新时间:2023-12-01 13:05:40 25 4
gpt4 key购买 nike

在以下代码(godbolt link)中:

#include <utility>

struct Friend {
class Inner {
friend struct Friend;

int function() { return 0; }
};

using DirectResult = decltype(std::declval<Inner>().function());

template <typename T>
using IndirectResult = decltype(std::declval<T>().function());
};

int main() {
Friend::DirectResult direct{};
Friend::IndirectResult<Friend::Inner> indirect{};
return direct + indirect;
}

Clang 对使用 DirectResult 非常满意,但会提示 IndirectResult正在尝试访问 private Inner的功能:
<source>:13:55: error: 'function' is a private member of 'Friend::Inner'    
using IndirectResult = decltype(std::declval<T>().function());
^
<source>:18:13: note: in instantiation of template type alias 'IndirectResult' requested here
Friend::IndirectResult<Friend::Inner> indirect{};
^

我原以为访问会很好,因为模板别名是在 friend 类中声明的。

但是,根据我的经验,在解释 C++ 标准时,Clang 通常是正确的(比 gcc 更正确)。

Clang 拒绝此代码是否正确? 如果是这样,我错过了什么?

注意:gcc 7.x、8.x 和 9.x 接受代码。

最佳答案

这是a bug在铿锵。根据 [class.friend]/2 :

Declaring a class to be a friend implies that the names of private and protected members from the class granting friendship can be accessed in the base-specifiers and member declarations of the befriended class.



根据 [class.mem] ,模板声明可以是成员声明,​​并且根据 [temp.pre]/2.5别名声明可以是模板声明中的声明。因此成员别名模板可以访问类(class) friend 的私有(private)成员和 protected 成员。

幸运的是,该错误似乎仅适用于别名声明的定义类型 ID。您可以通过将计算移至辅助类(带有嵌套 type 别名)或更简洁地移至默认模板参数来解决此问题:
template <typename T, class U = decltype(std::declval<T>().function())>
using IndirectResult = U;

关于c++ - friend 、私有(private)函数、模板别名和 decltype ......在拒绝这个方面是正确的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61410959/

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