Visual Studio 2017是否完全支持具有[[deprecated]]属性的N4266?

Bro*_*her 5 c++ visual-studio c++17

我正在研究C++ 17的新功能.我偶然发现了N4266这个功能,它说现在枚举和名称空间也可以使用属性.不同消息来源称,Visual Studio 2017已经完全支持此功能.我用[[deprecated]]属性编写了一个测试.对于名称空间,这非常有效.但是,没有为枚举生成警告.我的实施中有错误吗?我错过了什么?

enum MyEnum
{
    val = 0,
    vaal[[deprecated]] = val
};

void test()
{
    MyEnum e  = MyEnum::vaal; //Should emit Warning, but does not
    MyEnum e2 = MyEnum::val;  //No Warning
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Visual Studio Community 2017版本15.3.5.说明自VS2015以来它应该得到支持./ std:使用c ++ 17.

也说明这应该是正确的语法.

如果我使用枚举或枚举类没有区别.

dfr*_*fri 3

不,不完全是。

\n\n

我想说这是 MSVC2017 中的当前限制/错误,可能值得提交错误报告,即使该属性也在枚举器情况下被识别(并且不会提示 C5030 警告;正如 Mark 在对你的问题的评论)。

\n\n

附录:现已通过 Hans Passant 提供的链接进行验证(作为先前已知的错误):

\n\n\n\n
\n\n

C++17(工作草案)标准[decl.attr.deprecated]指出:

\n\n
\n

\xc2\xa71 属性令牌deprecated可用于标记仍然允许使用但由于某些原因不鼓励使用的名称和实体。

\n\n

\xc2\xa73 该属性可以应用于类、类型定义名称、变量、非静态数据成员、函数、命名空间、枚举、枚举或模板的声明\n 专业化。...

\n
\n\n

/std:c++17使用MSVC2017 编译时使用该标志,该deprecated属性适用于除枚举器之外的所有上述内容:

\n\n
// a class\nclass [[deprecated]] MyClass {};\n\n// a typedef-name / type alias\n[[deprecated]] typedef int MyInt;\nusing MyFloat [[deprecated]] = float;\n\n// a variable (see main)\n\n// a non-static data member\nstruct DataMember\n{\n    int b [[deprecated]];\n};\n\n// a function\n[[deprecated]]\nvoid myFunction() {}\n\n// a namespace\nnamespace [[deprecated]] my_namespace\n{\n    typedef double MyDouble;\n}\n\n// an enumeration\nenum [[deprecated]] MyEnum {};\n\n// an enumeration\nenum MyNewEnum\n{\n    val[[deprecated]] = 42\n};\n\n// a template specialization\ntemplate <typename T>\nvoid myTemplateFunction(const T) {} \n\ntemplate<>\n[[deprecated]]\nvoid myTemplateFunction<int>(const int) {}\n\nint main()\n{\n    MyClass m; // warning C4996: \'MyClass\': was declared deprecated\n    MyInt i;   // warning C4996: \'MyInt\': was declared deprecated\n    MyFloat f; // warning C4996: \'MyInt\': was declared deprecated\n    int j [[deprecated]];\n    j = 1;     // warning C4996: \'j\': was declared deprecated\n    DataMember dm;\n    dm.b = 1;  // warning C4996: \'DataMember::b\': was declared deprecated\n    myFunction();\n               // warning C4996: \'myFunction\': was declared deprecated\n    my_namespace::MyDouble d; \n               // warning C4996: \'my_namespace\': was declared deprecated\n    MyEnum e;  // warning C4996: \'MyEnum\': was declared deprecated\n    myTemplateFunction(2);\n               // warning C4996: \'myTemplateFunction\': was declared deprecated\n\n    MyNewEnum ne = val; // ... no warning\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

gcc 和 clang 都会对MyNewEnum ne = val;上述、for-std=c++14以及-std=c++1z.

\n\n

在相关说明中,特别是cppreference 的deprecated属性描述似乎没有使用 N4266 进行更新,在有效的用例声明中不包括“枚举器”和“命名空间”;尽管它们都存在于C++14 标准草案 (7.6.5/2)中。这可能表明这是一个很少使用的功能(应用于枚举器/命名空间),这可以解释为什么它在 MVCS 中(部分)被遗漏。

\n\n
    \n
  • 编辑:添加了有关此的注释,现已更正。
  • \n
\n\n

官方 MVSC 文档中存在一些含糊之处

\n\n

最后,MSVC 文档中的属性部分并没有真正深入地指定deprecated允许该属性的声明类型;仅显示弃用函数声明的示例。

\n\n

尽管,正如您所指出的(但是通过链接到 cppreference 而不是 MSVC 自己的文档),MSVS2015 确实明确声明了与 N4266 的一致性,至少对于 C++17 而言。

\n\n
\n

编译器特性

\n\n

C++17 核心语言特性

\n\n

N4266 命名空间和枚举器的属性

\n\n

支持:VS2015

\n
\n\n

然而,Support For C++11/14/17 Features (Modern C++) 的说法相反(对于 VS2015):

\n\n
\n

编译器特性

\n\n

C++17 建议的核心语言功能

\n\n

N4266 命名空间和枚举器的属性

\n\n

支持VS2013: 否

\n\n

支持VS2015: 否

\n
\n