#include <iostream>
#include <memory>
class A
{
public:
static [[nodiscard]] std::unique_ptr<A> create();
virtual int get_version() = 0;
virtual ~A() = default;
};
class B : public A
{
public:
[[nodiscard]] int get_version() override
{
return 20;
}
};
std::unique_ptr<A>
A::create()
{
return std::make_unique<B>();
}
int main()
{
auto a = A::create();
[[maybe_unused]] int v = a->get_version();
}
我尝试使用[[nodiscard]]
来不允许忽略A::create()
的返回值。但是,我在GCC和Clang中得到不同的编译输出。
与尝试
- GCC: 8.5
- 叮当声:15.0.0
- 编译选项:- 3 -std=c++17
- Godbolt链接:https://godbolt.org/z/qa7TfcK9f
GCC:
<source>:7:12: warning: attribute ignored [-Wattributes]
static [[nodiscard]] std::unique_ptr<A> create();
^
<source>:7:12: note: an attribute that appertains to a type-specifier is ignored
ASM generation compiler returned: 0
<source>:7:12: warning: attribute ignored [-Wattributes]
static [[nodiscard]] std::unique_ptr<A> create();
^
<source>:7:12: note: an attribute that appertains to a type-specifier is ignored
Execution build compiler returned: 0
Program returned: 0
叮当声:
<source>:7:14: error: 'nodiscard' attribute cannot be applied to types
static [[nodiscard]] std::unique_ptr<A> create();
^
1 error generated.
ASM generation compiler returned: 1
<source>:7:14: error: 'nodiscard' attribute cannot be applied to types
static [[nodiscard]] std::unique_ptr<A> create();
^
1 error generated.
Execution build compiler returned: 1
我做错了什么吗?为什么这些编译器有不同的行为?
此代码与MSVC v19.33正常工作,没有任何错误或警告:https://godbolt.org/z/dWsv4jTo5
您可以在这里https://eel.is/c++draft/class.mem#general看到属性只能首先出现在成员声明中。因此,
static [[nodiscard]] std::unique_ptr<A> create();
是错误的。应该是
[[nodiscard]] static std::unique_ptr<A> create();
你的代码有一个错别字。
新版本的gcc报告一个更明确的错误:
source>:7:12: error: standard attributes in middle of decl-specifiers
7 | static [[nodiscard]] std::unique_ptr<A> create();
| ^
<source>:7:12: note: standard attributes must precede the decl-specifiers to apply to the declaration, or follow them to apply to the type
<source>:7:12: warning: attribute ignored [-Wattributes]
<source>:7:12: note: an attribute that appertains to a type-specifier is ignored
实际上我不知道它是否必须被报告为错误,或者如果一个警告是可以的。我不认为这真的很重要,因为你无论如何都需要修复它,除非你忽略警告,否则你不会错过它。MSCV不诊断这个问题是不好的。但是,您还应该记住,[[nodiscard]]
类似的属性只是鼓励编译器发出警告。当它被丢弃时,不能保证得到警告。