2

我有一个函数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用红色下划线显示以下消息:

期待一个声明

在第 12 行的“void test(TEnum v) [with TEnum=TestEnum]”实例化期间检测到

最后一个“else”的程序代码用红色下划线。

(我试过使用else constexpr而不是else,但这似乎并不重要。)

如果我删除最后一个else if -branch (检查uint64_t的那个),错误就会消失:

没有最后一个“else if”分支的程序代码,也没有错误消息。

这是 Visual Studio 中的错误,还是我做了不应该做的事情?

4

2 回答 2

1

我确信这实际上不是您期望的答案,但是……这段代码

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 年过去了,如果我们必须再添加两个角色,我们不会尖叫……好吧,我不是……

于 2018-09-08T18:05:52.597 回答
0

这似乎是 IntelliSense 中的一个错误。它与uint64_t或任何其他类型无关。8 个 if/else 分支以上的所有内容都开始产生此错误。随时向 Microsoft 报告

于 2018-09-09T00:06:23.457 回答