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

kh212irz  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(227)

我知道你可以使用static_cast<void>,但它对我来说似乎太冗长了,而且没有反映出我想要放弃返回值的初衷,而不是将其转换为任何东西。
最近我偶然发现了std::ignore,它可以接受任何类型的值,名称清晰可读,对我来说似乎很合适。
我知道最初的意图是使用std::ignorestd::tie来丢弃任何不需要的值,但我猜static_cast的最初意图是为了一些更好的原因而不是丢弃值,这样编译器就不会抱怨。
那么,可以使用std::ignore来实现我在问题中描述的目的吗?
举例来说:

std::ignore = std::transform(...);
jljoyd4f

jljoyd4f1#

是的,没关系。事实上,它被一些人认为是更好的风格。
不要强制转换为(void)以忽略[[nodiscard]]返回值。如果你故意想放弃这样的结果,首先要认真考虑这是否真的是一个好主意(通常有一个很好的理由,函数或返回类型的作者首先使用[[nodiscard]])。如果您仍然认为它是合适的,并且您的代码审阅者也同意,那么可以使用std::ignore =来关闭警告,这是一个简单、可移植且易于grep的方法。

  • CppCore指南ES.48:避免铸件

反对std::ignore的一个论点是,它只根据它在std::tie中的效果来定义:

template<class... TTypes>
constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
  • 返回 *:tuple<TTypes&...>(t...) .当t中的参数为ignore时,为相应的元组元素分配任何值都没有效果。
  • [实用程序] std::tie
    这主要是一个哲学问题。在每一个主要的标准库中,std::ignore都是以这样一种方式实现的,即您可以单独执行std::ignore = ...,这可能很快就会得到很好的定义。参见P2968: Make std::ignore a first-class object
    最后,这是风格偏好。您可以使用(void)static_cast<void>std::ignore。它们都是可以接受的,使用哪一个是一个意见问题。重要的是你在整个项目中使用一致的风格,即。如果在一个地方使用std::ignore丢弃结果,那么在任何地方都使用它。
nnsrf1az

nnsrf1az2#

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

[[nodiscard]] auto& operator=(auto&&...) const { return *this; }

因此,赋值给std::ignore可能会导致警告,而不是抑制编译器警告。
std::tupleoperator=可以做类似这样的事情,当std::ignoretuple的一部分时,可以抑制警告:

(static_cast<void>(std::get<I>(*this) = std::get<I>(rhs)), ...);

在实践中,没有实现像这样定义std::ignore
是否可以使用std::ignore =取决于您是否希望依赖于没有实现在std::ignore的定义中使用[[nodiscard]]的事实。就我个人而言,我宁愿不依赖这个没有记录的事实。

相关问题