模板参数相关[[nodiscard]]

cer*_*wny 7 c++ attributes c++17

我有一个功能对象,它是另一个功能的包装:

template <typename FuncT>
class Wrapper
{
    private:
        FuncT funcToWrap;

    public:
        Wrapper(FuncT ftw) : funcToWrap(ftw){};

        template<typename ...ARG>
        typename std::result_of<FuncT(ARG&&...)>::type operator()(ARG&&... args){
            return funcToWrap(std::forward<ARG>(args)...);
        }
};

int main(){
    std::function<void()> testfunc = [](){ std::cout << "Test" << std::endl; };
    Wrapper<decltype(testfunc)> test{testfunc};
    test();
}
Run Code Online (Sandbox Code Playgroud)

我想这样做是为了纪念operator()[[nodiscard]]如果std::result_of<FuncT(ARG&&...)>::type不是void

我注意到的是,当我将[[nodiscard]]返回类型的模板评估的情况设为时void,它将被编译器忽略。

这是我可以依靠的行为吗?

L. *_* F. 1

根据[dcl.attr.nodiscard]/2

\n\n
\n

[\xe2\x80\x89注意: nodiscard 调用是一个函数调用表达式,它调用\n 先前声明的函数nodiscard,或者其返回类型是\n 可能是 cv 限定的类或标记为 的枚举类型nodiscard。\n nodiscard 的外观除非显式转换为\n ,否则不鼓励将其作为潜在评估\n 丢弃值表达式进行调用 void。在这种情况下,实施应发出警告。这通常是因为丢弃 nodiscard 调用的返回值会产生令人惊讶的后果。—\xe2\x80\x89尾注]

\n
\n\n

我对本段的阅读表明,鉴于

\n\n
[[nodiscard]] void f() {}\n
Run Code Online (Sandbox Code Playgroud)\n\n

甚至

\n\n
f();\n
Run Code Online (Sandbox Code Playgroud)\n\n

应发出警告。您必须void显式转换为

\n\n
(void) f();\n
Run Code Online (Sandbox Code Playgroud)\n\n

来压制它。所以不,标准不保证这一点。

\n\n

在我看来,该标准只是忽略了这一微妙之处。

\n