检测私人成员的存在 [英] Detect existence of private member
问题描述
我想写一个类型特征以检查某个类型是否具有成员 member
。如果成员
是公开,则有许多方法可以做到这一点(例如 void_t
),这可能是 Yakk的 can_apply
(最终可以称为 std :: is_detected
):
I want to write a type trait to check if some type has a member member
. If member
were public, there are any number of ways to do this (e.g. void_t
), the most concise of which is probably Yakk's can_apply
(which could eventually be called std::is_detected
):
struct C {
int member;
};
template <typename T>
using member_type = decltype(&T::member);
template <typename T>
using has_member = can_apply<member_type, T>;
static_assert(has_member<C>{}, "!"); // OK
但是如果成员为 private ,则此特征失败,由于对成员
的访问格式不正确(我们不是朋友),并且由于访问原因而格式错误和由于此原因而导致格式错误之间没有区别-不存在的原因:
But if the member were private, this trait fails, since the access on member
is ill-formed (we are not friends) and there is no differentiation between ill-formed due to access reasons and ill-formed due to this-thing-doesn't-exist reasons:
class D {
int member;
};
static_assert(has_member<D>{}, "!"); // error
是否可以在所有访问控制中编写这样的成员检查器?
Is there a way to write such a member checker across all access controls?
推荐答案
确实存在一种用于非最终非工会类类型的方法:
There is indeed a way for non-final non-union class types:
namespace detail {
struct P {typedef int member;};
template <typename U>
struct test_for_member : U, P
{
template <typename T=test_for_member, typename = typename T::member>
static std::false_type test(int);
static std::true_type test(float);
};
}
template <typename T>
using test_for_member =
std::integral_constant<bool, decltype(detail::test_for_member<T>::test(0)){}>;
演示 。诀窍是检查对不同基类的查找是否会产生歧义。 [class.member.lookup] / 2:
Demo. The trick is to check whether lookup into different base classes will yield an ambiguity. [class.member.lookup]/2:
成员名称查找确定名称的含义( id-expression )
在类范围(3.3.7)中。名称查找可能会导致歧义,在
中会导致程序格式错误。 […]名称查找发生在访问控制之前($ 3.4,第11条)。
Member name lookup determines the meaning of a name (id-expression) in a class scope (3.3.7). Name lookup can result in an ambiguity, in which case the program is ill-formed. […] Name lookup takes place before access control (3.4, Clause 11).
请注意,GCC的查找已损坏只要它忽略在 typename-specifier 中查找的非类型名称。
Note that GCCs lookup is broken insofar as it ignores non-type names for lookup in typename-specifiers.
这篇关于检测私人成员的存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!