c++ - 我可以使用本地声明的枚举类作为模板非类型参数吗? (gcc 给出模糊的错误)

标签 c++ c++11 gcc

以下代码无法在 gcc 4.8.1 到 6.3 中编译:

#include <cassert>

template<typename T, T X>
struct Mode {
    using type = Mode;
    using value_type = T;
    static constexpr value_type value = X;
^^^ error: 'constexpr const value_type Mode<main()::TestEnum, (main::TestEnum)0>::value', declared using local type 'const value_type {aka const main()::TestEnum}', is used but never defined [-fpermissive]
    constexpr operator value_type() const noexcept { return value; }
};

int main()
{
    enum class TestEnum { test1, test2 };
    constexpr Mode<TestEnum, TestEnum::test1> test1 = {};
    constexpr Mode<TestEnum, TestEnum::test2> test2 = {};

    assert(static_cast<TestEnum>(test1) == TestEnum::test1);
}

clang 3.9.1和MSVC 2015 SP3编译无误

如果我将 enum class TestEnum { test1, test2 }; 移动到全局范围内,那么它可以正确编译。

代码是否合法?还是我做错了什么?

最佳答案

我认为问题是,您仍然必须定义 Mode::value,正如编译器所说 (ODR)。如果我没记错的话,这会随着 C++17 发生变化,并且定义不再是强制性的,这解释了为什么它使用 std=c++1z 标志运行。

这也在“之前”std=c++1z 编译和运行:

#include <cassert>

template<typename T, T X>
struct Mode {
    using type = Mode;
    using value_type = T;
    static constexpr value_type value = X;

    constexpr operator value_type() const noexcept { return value; }
};

template<typename T, T X> constexpr T Mode<T,X>::value;

int main()
{
    enum class TestEnum { test1, test2 };
    constexpr Mode<TestEnum, TestEnum::test1> test1 = {};
    //constexpr Mode<TestEnum, TestEnum::test2> test2 = {};

    assert(static_cast<TestEnum>(test1) == TestEnum::test1);
}

您可以 see it live .

关于c++ - 我可以使用本地声明的枚举类作为模板非类型参数吗? (gcc 给出模糊的错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42328208/

相关文章:

c++ - 用 C++ 文件编译 C 共享对象

c++ - directx C++ 第一人称相机

c++ - Direct2D 和 Direct3D 互操作性的方法

c++11 - 在 OpenSSL v1.1.0 中使用 unique_ptr<SSL>

c++ - 以字符串列表作为模板参数的模板静态类,如何在C++ 11上制作

c - FILE 指针与标准输入不兼容

c++ - Linux 上的 x86 C++ 开发存在哪些(有效的)备用工具链?

c++ - Qt调用外部Python脚本

c++ - 在事件上使用 "Dispatch"函数的原因是什么?

用于多维数组的 C++ const_cast 运算符