我有一个函数test,它打印出枚举参数的基础类型:
enum class TestEnum : uint32_t
{
};
template<typename TEnum>
void test(TEnum v)
{ // Line 12
if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,int8_t>)
std::cout<<"int8"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,uint8_t>)
std::cout<<"uint8"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,int16_t>)
std::cout<<"int16"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,uint16_t>)
std::cout<<"uint16"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,int32_t>)
std::cout<<"int32"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,uint32_t>)
std::cout<<"uint32"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,int64_t>)
std::cout<<"int64"<<std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>,uint64_t>)
std::cout<<"uint64"<<std::endl;
else
static_assert(false,"Unsupported enum type!");
}
int main(int argc,char *argv[])
{
TestEnum e {};
test<TestEnum>(e);
return EXIT_SUCCESS;
}
该程序在 Visual Studio 2017(使用 ISO C++17)中编译和运行良好,但最后一个 else 带有红色下划线并显示以下消息:
expected a statement
detected during instantiation of "void test(TEnum v) [with TEnum=TestEnum]" at line 12
(我已经尝试使用 else constexpr 而不是仅仅使用 else,但这似乎并不重要。)
如果我删除最后一个 else if 分支(检查 uint64_t 的分支),错误就会消失:
这是 Visual Studio 中的错误,还是我做了不该做的事情?
最佳答案
我相信这实际上不是您期望的答案,但是…… 这段代码
enum class TestEnum : uint32_t
{
};
template<typename TEnum>
void test(TEnum v)
{ // Line 12
if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int8_t>)
{
std::cout << "int8" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint8_t>)
{
std::cout << "uint8" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int16_t>)
{
std::cout << "int16" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint16_t>)
{
std::cout << "uint16" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int32_t>)
{
std::cout << "int32" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint32_t>)
{
std::cout << "uint32" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int64_t>)
{
std::cout << "int64" << std::endl;
}
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint64_t>)
{
std::cout << "uint64" << std::endl;
}
else
{
static_assert(false, "Unsupported enum type!");
}
}
int main(int argc, char *argv[])
{
TestEnum e{};
test<TestEnum>(e);
return EXIT_SUCCESS;
}
不产生任何警告
不过
enum class TestEnum : uint32_t
{
};
template<typename TEnum>
void test(TEnum v)
{ // Line 12
if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int8_t>)
std::cout << "int8" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint8_t>)
std::cout << "uint8" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int16_t>)
std::cout << "int16" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint16_t>)
std::cout << "uint16" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int32_t>)
std::cout << "int32" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint32_t>)
std::cout << "uint32" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, int64_t>)
std::cout << "int64" << std::endl;
else if constexpr (std::is_same_v<std::underlying_type_t<TEnum>, uint64_t>)
std::cout << "uint64" << std::endl;
else
static_assert(false, "Unsupported enum type!");
}
int main(int argc, char *argv[])
{
TestEnum e{};
test<TestEnum>(e);
return EXIT_SUCCESS;
}
生成与您的第一个屏幕截图中相同的消息。我知道这是法语,但请相信我,它说的是一样的。
只是为了辩论,我从来没有真正理解为什么规范仍然允许
if(boolean) do;
同时
if(boolean) { do;}
完成工作并且没有任何歧义。 Fortran 77 允许的肯定是肮脏的继承。坦率地说,40 年过去了,如果我们必须再添加两个字符,我们不会尖叫……好吧,我不是……
关于c++ - constexpr if else 表达式中的 "Expected a statement",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52236344/