我目前正在调查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
}
我正在使用Visual Studio Community 2017版本15.3.5。 This表示自VS2015以来应该支持它。 / std:使用了c ++ 17。
And this也说应该是正确的语法。
如果我使用enum或enum类没有区别。
答案 0 :(得分:3)
不,不完全。
我想说这是MSVC2017中的当前限制/错误,可能值得提交错误报告,即使该属性也在枚举器情况下被识别(并且没有提示C5030警告;如Mark所述)在你的评论中提问)。
附录:现已通过Hans Passant提供的链接验证(作为先前已知的错误):
C ++ 17(工作草案)标准[decl.attr.deprecated]声明:
§1属性标记
deprecated
可用于标记名称和 仍允许使用的实体,但对某些人不鼓励 原因。§3该属性可以应用于类的声明,a typedef-name,变量,非静态数据成员,函数,a 名称空间,枚举,枚举器或模板 专业化。 ...
在使用MSVC2017进行编译时使用/std:c++17
标志,deprecated
属性适用于上述所有内容,但枚举器:
// a class
class [[deprecated]] MyClass {};
// a typedef-name / type alias
[[deprecated]] typedef int MyInt;
using MyFloat [[deprecated]] = float;
// a variable (see main)
// a non-static data member
struct DataMember
{
int b [[deprecated]];
};
// a function
[[deprecated]]
void myFunction() {}
// a namespace
namespace [[deprecated]] my_namespace
{
typedef double MyDouble;
}
// an enumeration
enum [[deprecated]] MyEnum {};
// an enumeration
enum MyNewEnum
{
val[[deprecated]] = 42
};
// a template specialization
template <typename T>
void myTemplateFunction(const T) {}
template<>
[[deprecated]]
void myTemplateFunction<int>(const int) {}
int main()
{
MyClass m; // warning C4996: 'MyClass': was declared deprecated
MyInt i; // warning C4996: 'MyInt': was declared deprecated
MyFloat f; // warning C4996: 'MyInt': was declared deprecated
int j [[deprecated]];
j = 1; // warning C4996: 'j': was declared deprecated
DataMember dm;
dm.b = 1; // warning C4996: 'DataMember::b': was declared deprecated
myFunction();
// warning C4996: 'myFunction': was declared deprecated
my_namespace::MyDouble d;
// warning C4996: 'my_namespace': was declared deprecated
MyEnum e; // warning C4996: 'MyEnum': was declared deprecated
myTemplateFunction(2);
// warning C4996: 'myTemplateFunction': was declared deprecated
MyNewEnum ne = val; // ... no warning
return 0;
}
对于MyNewEnum ne = val;
以及-std=c++14
,gcc和clang都会针对上面的-std=c++1z
调用弃用警告。
在相关的说明中,特别是cppreference's description of the deprecated
attribute似乎没有使用N4266更新,在有效用例声明中不包括“枚举器”和“命名空间”;即使这些都存在于C++14 standard draft (7.6.5/2)中。这可能是一个指示,这是一个很少使用的功能(应用于枚举器/命名空间),这可以解释为什么它(部分)错过了MVCS。
最后,attributes section in the MSVC docs并没有真正深入地指出允许deprecated
属性的哪种声明;仅显示弃用函数声明的示例。
尽管如你所指出的那样(但是通过链接到cppreference而不是MSVC自己的文档),MSVS2015 does explicitly state conformance to N4266,至少对于C ++ 17来说。
编译器功能
C ++ 17核心语言功能
N4266名称空间和枚举器的属性
支持:VS2015
然而,Support For C++11/14/17 Features (Modern C++)表明相反(对于VS2015):
编译器功能
C ++ 17提议的核心语言功能
N4266名称空间和枚举器的属性
支持VS2013:否
支持VS2015:否