C++ 我可以使用本地声明的枚举类作为模板非类型参数吗?(gcc给出模糊错误)
以下代码未能在gcc 4.8.1至6.3中编译: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; ^^^错
#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);
}