我们假设您需要调用以下方法:
std::tuple<int, int, int> foo();
Run Code Online (Sandbox Code Playgroud)
在C++ 17中,您可以调用该函数并在一行中解压缩元组:
auto [a, b, c] = foo();
Run Code Online (Sandbox Code Playgroud)
现在,我怎么能继续只存储b和c并丢弃a?
目前,我只知道两个选项:
1 - 我可以在自动解包时使用虚拟变量
但是,虚拟变量将被取消并且它将发出警告,因此如果我想要静默警告,那么代码将非常不愉快:
#pragma warning(push)
#pragma warning(disable:4101)
// ReSharper disable once CppDeclaratorNeverUsed
auto [_, b, c] = foo();
#pragma warning(pop)
Run Code Online (Sandbox Code Playgroud)
2 - 我可以存储整个元组并用于std::get检索对我需要的唯一变量的引用.代码不那么令人不愉快,但语法也不那么简单.
此外,对于我们希望保留在元组中的每个新值,此代码的大小增加一行.
auto tuple = foo();
int b = std::get<1>(tuple);
int c = std::get<2>(tuple);
Run Code Online (Sandbox Code Playgroud)
还有另一个更直接的方法来解包元组中的一些参数吗?
Man*_*uro 42
另一种选择是使用std::tie:
int b, c;
std::tie(std::ignore, b, c) = foo();
Run Code Online (Sandbox Code Playgroud)
编辑
正如评论中所提到的,这种方法存在一些问题:
Vit*_*meo 39
不幸的是,结构化绑定不明确支持丢弃成员,并且诸如[[maybe_unused]]不能应用于结构化绑定的属性(有一个提议:P0609:"结构化绑定的属性").
这是一个可能的解决方案:
auto [a, b, c] = foo();
(void) a; // unused
Run Code Online (Sandbox Code Playgroud)
Bar*_*rry 21
您可以编写一个辅助函数,只返回某些索引std::tuple:
template <size_t... Is, typename Tuple>
auto take_only(Tuple&& tuple) {
using T = std::remove_reference_t<Tuple>;
return std::tuple<std::tuple_element_t<Is, T>...>(
std::get<Is>(std::forward<Tuple>(tuple))...);
}
auto [b, c] = take_only<1, 2>(foo());
Run Code Online (Sandbox Code Playgroud)
或掉头或其他东西:
template <size_t... Is, typename Tuple>
auto drop_head_impl(Tuple&& tuple, std::index_sequence<0, Is...> ) {
return take_only<Is...>(std::forward<Tuple>(tuple));
}
template <typename Tuple>
auto drop_head(Tuple&& tuple) {
return drop_head_impl(std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>());
}
auto [b, c] = drop_head(foo());
Run Code Online (Sandbox Code Playgroud)
但是上面的实现几乎肯定会有一些终身复杂性问题直接使用结构化绑定不会 - 因为这里没有任何生命周期扩展.
所以,维托里奥说:
auto [a, b, c] = foo();
(void)a;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3944 次 |
| 最近记录: |