在模板类的constexpr函数中找到正确的宏常量

时间:2014-04-12 15:47:16

标签: c++ c++11 macros constexpr

有一个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的最佳方法是什么?

3 个答案:

答案 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 tokenTAG(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是否始终在编译时知道或者可能是某些外部函数的可变参数?