Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以使用本地声明的枚举类作为模板非类型参数吗?(gcc给出模糊错误)_C++_C++11_Gcc - Fatal编程技术网

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

C++ 我可以使用本地声明的枚举类作为模板非类型参数吗?(gcc给出模糊错误),c++,c++11,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; #包括 模板 结构模式{ 使用类型=模式; 使用值_type=T; 静态constexpr值\u类型值=X; ^^^错

以下代码未能在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;
#包括
模板
结构模式{
使用类型=模式;
使用值_type=T;
静态constexpr值\u类型值=X;
^^^错误:“constexpr const value_type Mode::value”,使用本地类型“const value_type{aka const main()::TestEnum}声明,但从未定义[-fppermissive]
constexpr运算符值_type()const noexcept{return value;}
};
int main()
{
枚举类TestEnum{test1,test2};
constexpr模式test1={};
constexpr模式test2={};
断言(static_cast(test1)=TestEnum::test1);
}
clang 3.9.1和MSVC 2015 SP3编译它时没有错误

如果我移动
enum类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);
}
#包括
模板
结构模式{
使用类型=模式;
使用值_type=T;
静态constexpr值\u类型值=X;
constexpr运算符值_type()const noexcept{return value;}
};
模板constexpr T Mode::value;
int main()
{
枚举类TestEnum{test1,test2};
constexpr模式test1={};
//constexpr模式test2={};
断言(static_cast(test1)=TestEnum::test1);
}

您可以。

我想说的是,在v6.x之前有一个GCC错误。GCC 7编译它。@skypjack您的GCC版本是什么?godbolt.org上的GCC 7给出了相同的错误:尝试了。@skpjack,你能发布一个到GCC 7的链接吗?在线查找最多6.3个。Thx。@skypjack
    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);
}
#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);
}