template<class T> class has_rc {
typedef char yes;
typedef long no;
template<class S, S> struct sig; // requiring an exact signature match to exclude possibility of inheriting the trait
template<class C> static yes test(sig<void(*)(C), &C::_rc_class_only>*);
template<class C> static no test(...);
public:
enum Boolean { value = sizeof(test<T>(0)) == sizeof(yes) };
};
// Macro for adding the trait. All trait related irrelevant code removed, only the trait marker for use in "has_rc".
// The "Class" is in my case auto-generated via macros, added here as a parameter instead for clarity.
#define RC(Class) public: static void _rc_class_only(Class) {}
struct TestRCnot {};
TEST(!has_rc<TestRCnot>::value); // value = false, no RC trait
struct TestRC { RC(TestRC); }; // value = true, have RC trait
TEST( has_rc<TestRC>::value);
struct TestRCderived : TestRC { }; // value = false, no RC trait *trait is not inheritable!*
TEST(!has_rc<TestRCderived>::value);
struct TestRC2 : TestRCderived { RC(TestRC2); }; // value = true, have RC trait *re-adding a trait is OK*
TEST( has_rc<TestRC2>::value);
Question, can i simplify this code? Anything pointlessly complex? Would like "_rc_class_only" to be private, but it fails to compile (TestRCderived) even if i friend the "has_rc" class.Note: can not use "constexpr".