当应用于函数时,[[nodiscard]]
属性会鼓励编译器如果将其用于除强制转换为void
以外的其他丢弃表达式中,则发出警告。示例:
[[nodiscard]] int callable_return_not_discardable(int n)
{ return n; }
int main()
{
callable_return_not_discardable(0); // warning/error:
// ignoring return value of 'int callable_return_not_discardable(int)',
// declared with attribute nodiscard [-Wunused-result]
(void) callable_return_not_discardable(0); // OK
}
这很好并且有用,直到添加了附加的间接层:模板:
template<class Callable>
void invoke_with_answer(Callable&& callable)
{ callable(42); }
[[nodiscard]] int callable_return_not_discardable(int n)
{ return n; }
int main()
{
invoke_with_answer(callable_return_not_discardable); // OK
}
我的问题是:
这是缺少的功能吗,是由于模板是什么,还是应该修复clang和gcc以便在此处发出警告?
答案 0 :(得分:8)
[[nodiscard]]
不是函数签名或类型的一部分,并且在将所述函数转换为指针或绑定到引用时根本不保留。这正是您的示例所做的。
出于所有目的和目的,模板无法“看到”属性。
答案 1 :(得分:2)
由于explained by StorryTeller,[[nodiscard]]
不是函数签名或类型的一部分,这就是为什么该信息会在模板主体的上下文中丢失的原因。
一种传播警告的解决方案是将[[nodiscard]]
属性添加到该函数的返回类型:
template<class Callable>
void invoke_with_answer(Callable&& callable)
{ callable(42); } // warning
struct [[nodiscard]] Int { int value; };
Int callable_return_not_discardable(int n)
{ return {n}; }
int main()
{
invoke_with_answer(callable_return_not_discardable); // note
}