【发布时间】:2013-03-03 15:45:59
【问题描述】:
我在玩SFINAE,但我试图在处理宏生成的代码时获取一些有意义的编译器错误信息。我使用THIS answer 来运行以下命令: (我想用 member_test(a) 检查 Type A 是否有一些之前定义的成员)
//Check for member variable with given name.
#define CREATE_MEMBER_VAR_CHECK(var_name) \
\
template<typename T, typename = std::true_type> \
struct has_member_var_##var_name : std::false_type {}; \
\
template<typename T> \
struct has_member_var_##var_name< \
T \
, std::integral_constant< \
bool, std::is_member_object_pointer<decltype(&T::var_name)>::value \
> \
> : std::true_type {};
#define MEMB_CHECK_WRAPPER(r, data, elem) CREATE_MEMBER_VAR_CHECK(elem)
#define CREATE_ENABLE_IF_CLAUSE(var_name) \
class = typename std::enable_if<has_member_var_##var_name<T>::value>::type
#define ENABLE_IF_CLAUSE_WRAPPER(r, data, i, elem) \
BOOST_PP_COMMA_IF(i) CREATE_ENABLE_IF_CLAUSE(elem)
#define TO_MEMBER_TEST(member_seq) \
BOOST_PP_SEQ_FOR_EACH(MEMB_CHECK_WRAPPER, _, member_seq) \
\
template < typename T, \
BOOST_PP_SEQ_FOR_EACH_I(ENABLE_IF_CLAUSE_WRAPPER, _, member_seq) \
> \
void member_test(const T & ) \
{ \
std::cout << "works!!\n\n"; \
}
当我执行以下操作时,一切都会好起来的:
TO_MEMBER_TEST((x)(y)(z))
struct A { int x, y, z; };
int main(int argc, char const *argv[])
{
A a;
member_test(a);
}
但是,当我改用 TO_MEMBER_TEST((x)(y)(z)(dummy)) 时,代码将无法编译(按预期),因为 member_test(A&) 不再定义,因为 A.dummy 不存在。编译器会给我类似的东西:
模板参数推导/替换失败:错误:'struct std::enable_if' 中没有名为'type'的类型
我怎么能说“没有会员假人”之类的话。而是(例如使用 static_asserts)?
【问题讨论】:
-
抱歉,我不得不更新标题。我发现THIS...看起来几乎正确...
标签: c++ c-preprocessor metaprogramming sfinae