我想写一个类型特征来检查某个类型是否有成员member
。如果 member
是 public,则有多种方法可以做到这一点(例如 void_t
),其中最简洁的可能是 Yakk's can_apply
(最终可以称为 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,则此 trait 失败,因为对 member
的访问是不正确的(我们不是 friend )并且 ill 之间没有区别- 由于访问原因而形成,由于这件事不存在的原因而形成不良:
class D {
int member;
};
static_assert(has_member<D>{}, "!"); // error
有没有办法在所有访问控制中编写这样的成员检查器?
最佳答案
对于非final非 union 类类型确实有办法:
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)){}>;
Demo .诀窍是检查查找不同的基类是否会产生歧义。 [class.member.lookup]/2:
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-specifiers 中查找的非类型名称。
关于c++ - 检测私有(private)成员的存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32566579/