kin*_*hah 3 c++ gcc clang c++17 nodiscard
#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();
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用[[nodiscard]]不允许忽略 的返回值A::create()。但是,我在 GCC 和 Clang 中得到不同的编译输出。
尝试过
海湾合作委员会:
<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
Run Code Online (Sandbox Code Playgroud)
铛:
<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
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?为什么这些编译器有不同的行为?
此代码与 MSVC v19.33 正常配合,没有任何错误或警告: https: //godbolt.org/z/dWsv4jTo5
您可以在此处看到https://eel.is/c++draft/class.mem#general该属性只能出现在成员声明的开头。因此这个
static [[nodiscard]] std::unique_ptr<A> create();
Run Code Online (Sandbox Code Playgroud)
是错的。并且应该是
[[nodiscard]] static std::unique_ptr<A> create();
Run Code Online (Sandbox Code Playgroud)
您的代码有一个拼写错误。
新版本的 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
Run Code Online (Sandbox Code Playgroud)
实际上我不知道是否必须报告错误或者警告也可以。我认为这并不重要,因为无论如何你都需要修复它,除非你忽略警告,否则你不会错过它。MSCV 不诊断问题并不好。但是,您还应该记住,[[nodiscard]]类似的属性只会鼓励编译器发出警告。不保证在丢弃时会收到警告。