C++ 元编程成员检查器不';t处理返回带有基类的类型的函数成员
我实现了一个元编程成员检查器,如下所示:C++ 元编程成员检查器不';t处理返回带有基类的类型的函数成员,c++,templates,metaprogramming,C++,Templates,Metaprogramming,我实现了一个元编程成员检查器,如下所示: //Declare a metaprogramming test to check if a class has a member //of a given signature and a certain name #define DECL_hasMember(MEMBER) \ /* Check if T has member MEMBER M is a
//Declare a metaprogramming test to check if a class has a member
//of a given signature and a certain name
#define DECL_hasMember(MEMBER) \
/* Check if T has member MEMBER M is a pointer to member of T type (T::*) */ \
template <typename T, typename M> \
class hasMember_##MEMBER { \
private: \
typedef char passed[1]; \
typedef char failed[2]; \
\
template <typename U, U> struct reallyHas; \
\
template <typename C> static passed& test(reallyHas<M, &C::MEMBER>*); \
template <typename C> static failed& test(...); \
\
hasMember_##MEMBER()=delete; \
public: \
static bool const value = sizeof(test<T>(nullptr)) == sizeof(passed); \
}
如前所述,静态断言失败,即它无法检测test::buildFSM
。问题出在desc\t
中,因为如果我将其更改为另一种类型,测试通过得很好。如果我修改了desc\t
,因此它不会派生std::map
,测试也会通过。为什么会发生这种情况?在这种情况下,我能做些什么来完成这项工作吗?我知道另一种选择是将map作为成员而不是基类,但我不明白为什么会发生这种情况
我在Visual Studio 2015中。结帐:
以下是一些用于检测成员函数的代码:
#include <iostream>
// single argument and return type
#define DECL_hasMemberRetArg(MEMBER) \
template<typename T, typename RESULT, typename ARG1> \
class Detect_RetArg_##MEMBER \
{ \
template <typename U, RESULT (U::*)(ARG1)> struct Check; \
template <typename U> static char func(Check<U, &U::MEMBER> *); \
template <typename U> static int func(...); \
public: \
typedef Detect_RetArg_##MEMBER type; \
enum { value = sizeof(func<T>(0)) == sizeof(char) }; \
}
// two arguments and return type
#define DECL_hasMemberRetArgArg(MEMBER) \
template<typename T, typename RESULT, typename ARG1, typename ARG2> \
class Detect_RetArgArg_##MEMBER \
{ \
template <typename U, RESULT (U::*)(ARG1, ARG2)> struct Check; \
template <typename U> static char func(Check<U, &U::MEMBER> *); \
template <typename U> static int func(...); \
public: \
typedef Detect_RetArgArg_##MEMBER type; \
enum { value = sizeof(func<T>(0)) == sizeof(char) }; \
}
class a_t
{
char get(int);
char put(int,long);
};
struct b_t
{
char get(int);
char put(int,long);
};
struct c_t : public b_t
{
};
DECL_hasMemberRetArg(get);
DECL_hasMemberRetArgArg(put);
int main()
{
std::cout << Detect_RetArg_get<a_t, char, int>::value << "\n"; // 0
std::cout << Detect_RetArgArg_put<a_t, char, int, long>::value << "\n"; // 0
std::cout << Detect_RetArg_get<b_t, char, int>::value << "\n"; // 1
std::cout << Detect_RetArgArg_put<b_t, char, int, long>::value << "\n"; // 1
std::cout << Detect_RetArg_get<c_t, char, int>::value << "\n"; // 0
std::cout << Detect_RetArgArg_put<c_t, char, int, long>::value << "\n"; // 0
return 0;
}
#包括
//单参数和返回类型
#定义DECL_hasMemberRetArg(成员)\
模板\
类Detect_RetArg_35;##成员\
{ \
模板结构检查\
模板静态字符函数(检查*)\
模板静态int func(…)\
公众:\
typedef Detect_RetArg_35;#成员类型\
枚举{value=sizeof(func(0))==sizeof(char)}\
}
//两个参数和返回类型
#定义DECL_HasMemberRetarg(成员)\
模板\
类检测重新组织成员\
{ \
模板结构检查\
模板静态字符函数(检查*)\
模板静态int func(…)\
公众:\
typedef Detect_RetArgArg_35;##成员类型\
枚举{value=sizeof(func(0))==sizeof(char)}\
}
a类
{
字符获取(int);
字符put(int,long);
};
结构b_t
{
字符获取(int);
字符put(int,long);
};
结构c\u t:公共b\u t
{
};
DECL_hasMemberRetArg(get);
DECL_HasmemberRetarg(看跌期权);
int main()
{
std::难道我也在Visual Studio 2015中,这使我的编译器崩溃了吗?我不再感到惊讶了。这并不是用Clang或GCC编译的,这并不奇怪;在实例化FSM
时,test
是一个不完整的类型,但是您的静态\u assert
检查其成员,这当然是失败的。
#include <iostream>
// single argument and return type
#define DECL_hasMemberRetArg(MEMBER) \
template<typename T, typename RESULT, typename ARG1> \
class Detect_RetArg_##MEMBER \
{ \
template <typename U, RESULT (U::*)(ARG1)> struct Check; \
template <typename U> static char func(Check<U, &U::MEMBER> *); \
template <typename U> static int func(...); \
public: \
typedef Detect_RetArg_##MEMBER type; \
enum { value = sizeof(func<T>(0)) == sizeof(char) }; \
}
// two arguments and return type
#define DECL_hasMemberRetArgArg(MEMBER) \
template<typename T, typename RESULT, typename ARG1, typename ARG2> \
class Detect_RetArgArg_##MEMBER \
{ \
template <typename U, RESULT (U::*)(ARG1, ARG2)> struct Check; \
template <typename U> static char func(Check<U, &U::MEMBER> *); \
template <typename U> static int func(...); \
public: \
typedef Detect_RetArgArg_##MEMBER type; \
enum { value = sizeof(func<T>(0)) == sizeof(char) }; \
}
class a_t
{
char get(int);
char put(int,long);
};
struct b_t
{
char get(int);
char put(int,long);
};
struct c_t : public b_t
{
};
DECL_hasMemberRetArg(get);
DECL_hasMemberRetArgArg(put);
int main()
{
std::cout << Detect_RetArg_get<a_t, char, int>::value << "\n"; // 0
std::cout << Detect_RetArgArg_put<a_t, char, int, long>::value << "\n"; // 0
std::cout << Detect_RetArg_get<b_t, char, int>::value << "\n"; // 1
std::cout << Detect_RetArgArg_put<b_t, char, int, long>::value << "\n"; // 1
std::cout << Detect_RetArg_get<c_t, char, int>::value << "\n"; // 0
std::cout << Detect_RetArgArg_put<c_t, char, int, long>::value << "\n"; // 0
return 0;
}