为什么在不使用constexpr时会得到未定义的引用

时间:2017-09-12 15:37:09

标签: c++ clang c++14

我创建了一个模板类来提供有关枚举的详细信息。

template <typename TEnum>
struct enum_traits
{
    struct enumerators
    {
        constexpr static const size_t   size = 0;

        template <size_t TIndex>
        struct get {
            constexpr static TEnum       value = static_cast<TEnum>( 0 );
            constexpr static const char *identifier = ""; 
        };

    };
};

这适用于某些枚举 - 在本例中为MyEnum:

enum class MyEnum : int
{
    eValue1 = 2,
    eValue2 = 4,
    eValue3 = 7,
    eValue4 = 8,
    eValue5 = 11,
    eValue6 = 13,
};

template<>
struct enum_traits<MyEnum>
{
    struct enumerators
    {
        constexpr static const size_t size = 6;

        constexpr static const std::array<MyEnum, size> values{ {
                MyEnum::eValue1,
                MyEnum::eValue2 ,
                MyEnum::eValue3,
                MyEnum::eValue4 ,
                MyEnum::eValue5,
                MyEnum::eValue6 ,
            } };

        constexpr static const std::array<const char*, size> names{ {
            "eValue1",
            "eValue2",
            "eValue3",
            "eValue4",
            "eValue5",
            "eValue6",
            } };


     template <size_t TIndex>
     struct get {
         constexpr static const MyEnum       value{ values.at( TIndex ) };
         constexpr static const char* identifier{ names.at( TIndex ) };
        };
    };
};

我会在代码中使用它

auto name2 = enum_traits<MyEnum>::enumerators::names[2];

然而,当使用clang进行编译时,我收到此链接错误

L0039: reference to undefined symbol `enum_traits<MyEnum>::enumerators::names' in file "/generated_got_file/"

如果我使用windows平台的microsoft编译器进行编译,那么它可以正常工作。 如果我改变行使用constexpr如下所示,那也是有效的,但这不是我需要的。

constexpr auto name2 = enum_traits<MyEnum>::enumerators::names[2];

任何人都可以建议我为什么会收到错误以及我可以使用哪些可行的解决方法?

更新

解决方案是在cpp文件中的某个行

constexpr const std::array<MyEnum, enum_traits<MyEnum>::enumerators::size> enum_traits<MyEnum>::enumerators::values;
constexpr const std::array<const char*, enum_traits<MyEnum>::enumerators::size> enum_traits<MyEnum>::enumerators::names;

虽然vstudio似乎不需要显式定义clang,但显然需要为非整数数据成员定义存储

我认为我对constexpr感到困惑,因为我拥有静态数据成员的通常方法是在头文件中声明它们并在源代码中定义它们。使用constexpr静态数据成员,似乎是相反的方式。

0 个答案:

没有答案