当成员为const和私有成员时,我正在尝试为成员检测器构建特征。我可以使用 wikibook中的成语DetectX
template<typename T>
class DetectX
{
struct Fallback { int X; }; // add member name "X"
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
typedef char ArrayOfOne[1]; // typedef for an array of size one.
typedef char ArrayOfTwo[2]; // typedef for an array of size two.
template<typename U>
static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
template<typename U>
static ArrayOfTwo & func(...);
public:
typedef DetectX type;
enum { value = sizeof(func<Derived>(0)) == 2 };
};
但是这个习惯用法并没有在私有const成员函数和私有非const成员函数之间进行区分,只是碰巧同时检测到non-const
和const
private
成员函数。
我认为当您取const
的地址时,(&U::X)
信息就会丢失。
我如何检测私有成员函数并区分同一类的const和非const私有成员函数?
查看Tyker的代码后,我可以使用friend获得C ++ 03实现。我还在等没有朋友的情况下解决问题。
/* Start - decltype simulation in c++03 */
template <size_t>
struct TypeId;
#define REGISTER_TYPE(T, id) \
template <> \
struct TypeId<id> { \
char value[id]; \
typedef T type; \
static char const* const name; \
}; \
char const* const TypeId<id>::name = #T; \
TypeId<id> type_to_id(T);
#define TYPEID_(value) TypeId<sizeof(type_to_id(value))>
#define TYPEOF(value) typename TYPEID_(value)::type
#define TYPENAME(value) TYPEID_(value)::name
REGISTER_TYPE(int, 1)
REGISTER_TYPE(unsigned int, 2)
/* End - decltype simulation - c++03 */
template <typename T>
class DetectX {
template <typename V>
struct Check;
template <typename U>
static char& func(
Check<TYPEOF((*(const U*)0).mem())>*); // use const U* or U*
template <typename U>
static short& func(...);
public:
typedef DetectX type;
enum { value = sizeof(func<T>(0)) }; // returns 1 or 2
};
class bar {
private:
int mem() const;
template <typename T>
friend class DetectX;
};
/* Register class and function signatures */
#define REGISTER_CLASS(X) \
typedef int (X::*pf)(); \
typedef int (X::*pfc)() const;
REGISTER_CLASS(bar)
REGISTER_TYPE(pf, 3)
REGISTER_TYPE(pfc, 4)
int main() { std::cout << DetectX<bar>::value << std::endl; }
答案 0 :(得分:0)
从std::declval<T>()
生成对象,然后将其强制转换为const,然后调用成员函数。在SFINAE函数中执行此操作。该函数应具有两个具有不同返回类型的重载版本。使用decltype
和std::is_same
检查返回类型,以了解成员函数是否为const限定。
答案 1 :(得分:0)
可以使用以下代码检测const私有成员。
唯一的缺点是朋友声明,但我认为没有它就无法做到。
template<typename T, typename...>
using first_type = T;
class private_const_test {
template<typename = void>
static constexpr std::false_type has_const_test_impl(...) {
return std::false_type();
}
template<typename T>
static constexpr first_type<std::true_type, decltype(std::declval<const T>().test())> has_const_test_impl(T) {
return std::true_type();
}
public:
template<typename T>
static constexpr bool has_const_test = decltype(has_const_test_impl(std::declval<T>()))::value;
};
class public_const_test {
template<typename = void>
static constexpr std::false_type has_const_test_impl(...) {
return std::false_type();
}
template<typename T>
static constexpr first_type<std::true_type, decltype(std::declval<const T>().test())> has_const_test_impl(T) {
return std::true_type();
}
public:
template<typename T>
static constexpr bool has_const_test = decltype(has_const_test_impl(std::declval<T>()))::value;
};
template<typename T>
constexpr bool has_private_const_test = private_const_test::has_const_test<T> && !public_const_test::has_const_test<T>;
struct A {
friend class private_const_test;
private:
void test() const {}
};
struct B {
friend class private_const_test;
void test() const {}
};
int main()
{
std::cout << has_private_const_test<A> << std::endl; // true
std::cout << has_private_const_test<B> << std::endl; // false
std::cout << has_private_const_test<int> << std::endl; // false
}