这个问题是一个跟进这一个
概念未实例化([temp.spec]).[注意:表示概念特化的id表达式被计算为表达式([expr.prim.id]).[...]
因此,可能由于可访问性而将名称概念特化的表达式赋予不同的值.
如果是这种情况,我想知道将在哪个上下文中评估表达式:
概念定义的背景;
表达的背景;
表达式的上下文递归地应用于概念定义中出现的概念表达式?
例如,什么可能是A::b2和A::b2_rec?的价值?
template<class T>
concept has_private = requires(){ &T::private_;};
template<class T>
concept has_private_rec = has_private<T>;
class B{
int private_;
friend class A;
};
inline constexpr bool b1 = has_private<B>;//I expects false
inline constexpr bool b1_rec = has_private_rec<B>;//I expects false
class A{
static constexpr bool b2 = has_private<B>; //?
static constexpr bool b2_rec = has_private_rec<B>; //?
};
Run Code Online (Sandbox Code Playgroud)
注意Clang实验概念和gcc概念TS实现产生b1和b1_rec的编译错误,但b2和b2_rec为真;
在下面的代码中,类A有一个私有成员函数f。我想编写一个静态断言来检查该函数是否可以从当前上下文访问(正如对此问题的评论中所建议的那样)。
类似的情况还有3个,都是基于requires-表达式:
class A{ void f(); };
// #1: accepted by all
static_assert( { return requires(decltype(x) a){ a.f(); }; }(A{}) );
// #2: rejected by Clang:
static_assert( { return requires(A a){ a.f(); }; }(nullptr) );
// #3: rejected by all
static_assert( { return requires(A a){ a.f(); }; }(nullptr) );
Run Code Online (Sandbox Code Playgroud)
案例 #3(以及 Clang 中的案例 #2)被拒绝并出现错误:
error: 'f' is a private member of 'A'
Run Code Online (Sandbox Code Playgroud)
演示: https: //gcc.godbolt.org/z/Mxs4P7x8s
为什么需求表达式在模板和非模板中的行为不同(案例 #1 和 #3)?#2 中哪个编译器是正确的?