有一个C头包含很长的宏常量列表,如下所示:
#define MODE_1_A 101
#define MODE_1_AB 21
#define MODE_1_ABC 9901
#define MODE_2_A 1031
#define MODE_2_AB 347
#define MODE_2_ABC 692
...
虽然宏名称遵循非常规则的模式,但遗憾的是无法可靠地计算常量。
我想写一个模板类,它可以将正确的模式整数作为constexpr
返回。
template<unsigned C, unsigned M>
struct MyClass
{
constexpr int mode() {
// C = 1 & M == 1 => return MODE_1_A
// C = 1 & M == 2 => return MODE_1_AB
// and so on
}
... // a lot of additional code
};
撰写constexpr
函数mode
的最佳方法是什么?
答案 0 :(得分:2)
使用预处理器!使用Boost.Preprocessor库:
#include <boost/preprocessor.hpp>
#define BOOST_PP_LOCAL_MACRO(n) \
template<> struct MyClass<n, 1> { \
constexpr int mode() { return BOOST_PP_CAT(BOOST_PP_CAT(MODE_, n), _A); } }; \
template<> struct MyClass<n, 2> { \
constexpr int mode() { return BOOST_PP_CAT(BOOST_PP_CAT(MODE_, n), _AB); } }; \
template<> struct MyClass<n, 3> { \
constexpr int mode() { return BOOST_PP_CAT(BOOST_PP_CAT(MODE_, n), _ABC); } }; \
#define BOOST_PP_LOCAL_LIMITS (1, 10)
#include BOOST_PP_LOCAL_ITERATE()
答案 1 :(得分:2)
您可以专门研究该方法:
template<unsigned C, unsigned M>
struct MyClass
{
static constexpr int mode();
};
template<> constexpr int MyClass<1, 1>::mode() { return 101; }
template<> constexpr int MyClass<1, 2>::mode() { return 21; }
来自Macro for mapping integer to string for token的TAG(N, C)
:
#define DEFINE_MODE(N,C) \
template<> constexpr int MyClass<N, C>::mode() { return TAG(N, C); }
DEFINE_MODE(1, 1)
DEFINE_MODE(1, 2)
DEFINE_MODE(2, 1)
// ...
答案 2 :(得分:-1)
你可以坚持使用宏:
#define MODE(a,b) MODE_##a##_##b
然后像这样使用它:
std::cout << MODE(2,ABC) << std::endl;
您的问题错过了有关如何将整数M拼接到字符串A,AB,ABC的信息...此外,C和M是否始终在编译时知道或者可能是某些外部函数的可变参数?