您可以創建另一個類MemberBase
是不有一個成員,然後繼承兩個類(類檢查T
和BaseMember
),並嘗試訪問該子類的成員。如果T
也有member
成員,那麼您將會遇到一個模糊問題。
代碼:
#include <type_traits>
// Yakk's can_apply
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
template<class...>struct types{using type=types;};
namespace details {
template<template<class...>class Z, class types, class=void>
struct can_apply : std::false_type {};
template<template<class...>class Z, class...Ts>
struct can_apply< Z, types<Ts...>, void_t< Z<Ts...> > >:
std::true_type
{};
}
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z,types<Ts...>>;
// Main code
class MemberBase {
public:
int member;
};
template<class ToCheck>
class MemberCheck: public ToCheck, public MemberBase {
};
template <typename T>
using member_type = decltype(&T::member);
template <typename T>
using hasnot_member = can_apply<member_type, MemberCheck<T>>;
template <typename T>
using static_not = std::integral_constant<bool, !T::value>;
template <typename T>
using has_member = static_not<hasnot_member<T>>;
// Tests
class A {
int member;
};
class Ap {
public:
int member;
};
class B {
float member;
};
class C {
int member();
};
class D {
};
static_assert(has_member<A>{}, "!"); // ok
static_assert(has_member<Ap>{}, "!"); // ok
static_assert(has_member<B>{}, "!"); // ok
static_assert(has_member<C>{}, "!"); // ok
static_assert(has_member<D>{}, "!"); // fail
但是,這肯定聞起來像一個骯髒的黑客我。
不是想說這是個壞主意。我沒有資格這樣做。但我真的很好奇,會有什麼用呢?也就是說,查詢某種類型的「私人」特性的用例是什麼(你無法以任何方式訪問)? – DevSolar
請參閱http://stackoverflow.com/questions/257288/possible-for-c-template-to-check-for-a-functions-existence#264088 – mvw
如果'member'是私人的,您應該可以安全地重命名該成員不會破壞外部代碼,而只是恰好在使用您的類。能夠按照您使用的方式創建'has_member'模板將使其非常容易創建代碼,至少不會以另一種開發人員合理期望的代碼行事的方式行事。所以我分享DevSolar的問題:你有什麼用途? – hvd