是否可以使用 std::ignore 来丢弃函数的返回值以避免任何相关的编译器警告?

Nik*_*128 19 c++ gcc c++14

我知道您可以使用static_cast<void>,但它对我来说似乎太冗长了,并且没有反映我想要丢弃返回值而不是将其转换为任何东西的初衷。

最近我偶然发现std::ignore,它可以接受任何类型的值,名称清晰易读,对我来说似乎很合适。

我知道最初的意图是std::ignore与 一起使用std::tie来丢弃任何不需要的值,但我猜想 的最初意图static_cast是为了比丢弃值更好的原因而实际转换值,这样编译器就不会抱怨。

那么,可以用于std::ignore我在问题中描述的目的吗?

例如:

std::ignore = std::transform(...);
Run Code Online (Sandbox Code Playgroud)

Jan*_*tke 18

是的,没关系。事实上,有些人认为这是更好的风格。

\n
\n

切勿强制转换(void)为忽略[[nodiscard]]返回值。如果您故意想要丢弃这样的结果,请首先认真考虑这是否真的是一个好主意(函数或返回类型的作者通常有一个很好的理由[[nodiscard]])。如果您仍然认为 \xe2\x80\x99 合适并且您的代码审阅者同意,请使用std::ignore =来关闭警告,这是简单、可移植且易于 grep 的。

\n
\n

- CppCoreGuidelines ES.48:避免强制转换

\n

注:赫伯·萨特 (Herb Sutter) 制定了该指南。通过该std::ignore规则,您可以始终教导不要使用强制转换,并且不必为强制转换为例外void

\n

反对的理由std::ignore是它仅根据其效果来定义std::tie

\n
\n
template<class... TTypes>\nconstexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;\n
Run Code Online (Sandbox Code Playgroud)\n

返回tuple<TTypes&...>(t...). t当is中的参数时ignore,为相应的元组元素分配任何值都没有效果。

\n
\n

- [实用程序]std::tie

\n

但这主要是一个哲学问题。在每个主要的标准库中,都是以您可以自己std::ignore完成的方式实现的,并且这可能很快就会得到明确的定义。std::ignore = ...请参阅P2968:制作std::ignore一流的对象

\n

最后,这是风格偏好。您可以使用(void)static_cast<void>、 或std::ignore。它们都是可以接受的,使用哪一种则见仁见智。\n重要的是你在整个项目中使用一致的风格,即如果你习惯std::ignore在一个地方丢弃结果,那么在任何地方都使用它。

\n


cpp*_*ner 5

理论上,std::ignore可以operator=实现为:

[[nodiscard]] auto& operator=(auto&&...) const { return *this; }
Run Code Online (Sandbox Code Playgroud)

因此,分配 tostd::ignore可能会导致警告,而不是抑制编译器警告。

并且std::tuples可以做这样的事情,当is 是 a 的一部分operator=时抑制警告:std::ignoretuple

(static_cast<void>(std::get<I>(*this) = std::get<I>(rhs)), ...);
Run Code Online (Sandbox Code Playgroud)

实际上,没有std::ignore这样的实现定义。

是否可以使用取决于您是否希望依赖于定义中std::ignore =没有实现使用的事实。我个人不愿意依赖这个未记录的事实。[[nodiscard]]std::ignore