我有一个正在为我构建课程的宏。我想提供一个构造函数,如果类本身没有指定 int 作为其类型,则该构造函数接受 int 。宏看起来像:
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预处理器来接近手动打开和关闭此构造函数...
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)){};
但是,我不能用条件替换宏中的 0 。我想要这样的东西:
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("your url");
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
nameValuePair.add(new BasicNameValuePair("username", "username"));
nameValuePair.add(new BasicNameValuePair("lang", "en"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePair);
HttpResponse response = httpClient.execute(httpPost);
然而,这扩展到不太有用的东西:
{{1}}
环顾四周,似乎没有BOOST_PP_NOT_EQUAL用于此类比较。 (我知道宏扩展问题,并且已经建立了一些&#34; IMPL&#34;宏来试图让事情进一步扩展。但是,我不认为这是问题所在。)思考?
答案 0 :(得分:1)
如果其他人有问题需要这种专业化,我想发一个答案。如果您想要比较一组有限的类型/字符串并在编译时知道它们,那么此解决方案将起作用。这是支持int和uint8_t的示例。特殊构造函数只能为非int类型编写。
#include <boost/preprocessor.hpp>
#define TYPE_IS_int 0
#define TYPE_IS_uint8_t 1
#define CLASS_DECLARE(NAME, TYPE)\
class NAME {\
public: NAME(const TYPE& x) : value(x) {}\
BOOST_PP_EXPR_IF(BOOST_PP_CAT(TYPE_IS_, BOOST_PP_EXPAND(TYPE)), NAME(const int& x) : value(static_cast<TYPE>(x)) {})\
private: TYPE value; };
CLASS_DECLARE(MyIntType, int);
CLASS_DECLARE(MyUint8Type, uint8_t);
宏扩展为:
class MyIntType
{
public:
MyIntType(const int& x) : value(x) {}
private:
int value;
};
class MyUint8Type
{
public:
MyUint8Type(const uint8_t& x) : value(x) {}
MyUint8Type(const int& x) : value(static_cast<uint8_t>(x)) {}
private:
uint8_t value;
};
答案 1 :(得分:0)
我能够通过使int
中明确声明的构造函数不太受欢迎来解决这个问题。为此,我声明了一个可以从int
构造并转换回int
的简单类,然后在构造函数中使用此类而不是普通int
:
struct int_wrapper {
int value;
operator int() const { return value; }
int_wrapper(int x): value(x) {}
};
#define CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: \
NAME(const TYPE& x) : value(x) {}\
NAME(const int_wrapper& x) : value(static_cast<TYPE>(x)) {} \
private: \
TYPE value; \
};
这允许
CLASS_DECLARE(cfloat, float)
CLASS_DECLARE(cint, int)
int main()
{
cfloat f1(1.0);
cfloat f2(1);
cint i(2);
}
虽然请注意,如果您尝试传递自己的已声明operator int()
的类,则会产生问题。你原来的方法可以处理这个(将类转换为int
并调用int
构造函数),而我的方法不会,因为编译器不允许两个用户定义的转换(到int
然后到int_wrapper
)。
此外,我现在无法获得第二个被调用的构造函数,因为如果你有static_cast<TYPE>(x)
,这意味着每int
TYPE
应该可以转换为TYPE
你使用,但第一个构造函数就足够了。但是,如果您的第二个构造函数只是一个简化的示例,而您实际上并没有直接将TYPE
强制转换为int
,那么您可能会发现我的答案很有用。