首页 > 解决方案 > mingw 和 BOOST 预处理宏

问题描述

我用 Mingw 在我的 Windows PC 上安装了 BOOST。BOOST 安装基本上可以工作,但是当我使用宏时,我收到以下错误消息:

macro "BOOST_PP_NOT_EQUAL_1" defined here

在Linux下它可以工作!

有人在那里可以帮助我吗?或者至少给出一些提示。

这是我的马可的:

#include <iostream>
#include <ostream>
#include <set>

#include <boost/preprocessor.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

class EnumShowValue {
private:
    static bool showValueFlag;
public:
    explicit EnumShowValue(const bool flag) { EnumShowValue::showValueFlag  = flag; }

    static bool showValue() { return EnumShowValue::showValueFlag; }
};

inline std::ostream &operator <<(std::ostream &os, const EnumShowValue &) { return os; }

// Defines a entry of the enumerations either with an initialization value or with a default value.
#define ENUM_FIELD(C, T, ARGS)\
    BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_SIZE(ARGS), 2),\
                    BOOST_PP_TUPLE_ELEM(0, ARGS) = BOOST_PP_TUPLE_ELEM(1, ARGS),\
                    BOOST_PP_TUPLE_ELEM(0, ARGS)),

// Define output of a single enumeration value.
#define ENUM_OUTPUT_CASE(C, T, ARGS)\
    case T::BOOST_PP_TUPLE_ELEM(0, ARGS):\
        os << BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(0, ARGS));\
        break;

#define ENUM_INSERT(C, T, ARGS)\
    this->insert(T::BOOST_PP_TUPLE_ELEM(0, ARGS));

#define ENUM_DEFINE_SET(C, T, ARGS)\
    class Collection : public std::set<C> {\
    public:\
        Collection() : std::set<C>() {\
            BOOST_PP_SEQ_FOR_EACH(ENUM_INSERT, C, ARGS)\
        }\
    };\
    Collection  collection;

// Works only if the enumeration values are unique.
#define ENUM(C, T, ARGS) \
enum class C : T {\
BOOST_PP_SEQ_FOR_EACH(ENUM_FIELD, C, ARGS)\
};\
ENUM_DEFINE_SET(C, T, ARGS)\
std::ostream &operator <<(std::ostream &os, const C val);\
std::ostream &operator <<(std::ostream &os, const C val) {\
    switch (val) {\
    BOOST_PP_SEQ_FOR_EACH(ENUM_OUTPUT_CASE, C, ARGS)\
    default:\
        os << "illegal value: " << BOOST_PP_STRINGIZE(C);\
        if (!EnumShowValue::showValue()) {\
            os << '(';\
            if (sizeof(T) == 1) {\
                os << static_cast<int>(val);\
            } else {\
                os << static_cast<T>(val);\
            }\
            os << ')';\
        }\
    }\
    if (EnumShowValue::showValue()) {\
                    os << '(';\
                    if (sizeof(T) == 1) {\
                        os << static_cast<int>(val);\
                    } else {\
                        os << static_cast<T>(val);\
                    }\
                    os << ')';\
    }\
    return os;\
}

以及如何使用的示例:(它定义了一些日志记录级别)

namespace logging {
    ENUM(Level, unsigned char, ((DEBUG)(INFO)(WARNING)(ERR)))
}

标签: boostmacrosmingw32

解决方案


如果找到解决方案显示如下。

我无法解决的是一个更通用的解决方案,我可以在#define 或模板中定义枚举的名称、基本类型和值。

有谁知道如何做到这一点?

#include <cstdint>
#include <iostream>
#include <ostream>

#define Days\
    X(Monday, = 100)\
    X(Tuesday,)\
    X(Wednesday,)\
    X(Thursday,)\
    X(Friday,)\
    X(Saturday, = 110)\
    X(Sunday,)

enum class Weekdays : uint8_t {
    #define X(a, b) a b,
    Days
    #undef X
};

std::ostream &operator <<(std::ostream &os, const Weekdays e);

std::ostream &operator <<(std::ostream &os, const Weekdays e) {

    switch (e) {
        #define X(a, b) case Weekdays::a: os << #a; break;
        Days;
        #undef X
        default:
            os << "invalid value: Weekdays=" << uint64_t(e);
    }

    return os;
}

int main(const int /*argc*/, const char *const /*argv*/[]) {

    std::cout << Weekdays::Monday << std::endl;
    std::cout << Weekdays::Tuesday << std::endl;
    std::cout << Weekdays::Saturday << std::endl;
    std::cout << Weekdays(99) << std::endl;

    return EXIT_SUCCESS;
}

推荐阅读