Template ignores [[nodiscard]] attribute

[[nodiscard]] is not part of a function's signature or type, and not at all preserved when said function is converted to a pointer or bound to a reference. Which is exactly what your example does.

The template, for all intents and purposes cannot "see" the attribute.


As explained by StorryTeller, [[nodiscard]] is not part of a function's signature or type, this is why that information is lost in the context of the template body.

A solution to get that warning propagated would be to add the [[nodiscard]] attribute to the return type of that function:

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
}

Live demo on gcc-8