【发布时间】:2016-03-30 23:46:07
【问题描述】:
我有一个宏正在为我构建一个类。如果类本身没有将 int 指定为其类型,我想提供一个构造函数,该构造函数采用 int。宏看起来像:
CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: NAME(const TYPE& x) : value(x) {}\
private: TYPE value; };
我可以使用 boost 预处理器来手动打开和关闭这个构造函数...
CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: NAME(const TYPE& x) : value(x) {}\
BOOST_PP_EXPR_IF(0, NAME(const int& x) : value(static_cast<TYPE>(x)) {})\
private: TYPE value; };
但是,我不能用条件替换宏中的 0。我想要类似的东西:
CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: NAME(const TYPE& x) : value(x) {}\
BOOST_PP_EXPR_IF(BOOST_PP_NOT_EQUAL(TYPE, int), NAME(const int& x) : value(static_cast<TYPE>(x)) {})\
private: TYPE value; };
然而,这扩展为一些不太有用的东西:
BOOST_PP_EXPR_IIF_BOOST_PP_BOOL_BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_int(0,
BOOST_PP_NOT_EQUAL_int)(MyType(const int& x) : value(static_cast<int>(x)){};
环顾四周,似乎 BOOST_PP_NOT_EQUAL 并不适合这种类型的比较。 (我知道宏扩展问题并构建了一些“IMPL”宏来尝试进一步扩展。但是我不认为这是这里的问题。)想法?
【问题讨论】:
-
您的确切问题是否只是模棱两可的构造函数调用?为什么不使用模板?
-
除非您至少有一组有限的类型,否则我认为您不会在预处理器中比较类型名称。不过,您可以将其交给编译步骤而不是预处理步骤。
-
是的。我不能在这里使用模板,因为其他模板化函数和类需要使用这些类。然后,这将对#include 施加顺序依赖。一团糟。那是我的第一次尝试,实际上。 MSVC 很高兴,但 GCC 和 Clang 的抱怨是正确的。
-
@chris 我也尝试使用 std::enable_if<:is_same>
标签: c++ macros metaprogramming c-preprocessor boost-preprocessor