将元组和整型实例合并到引用元组中
Merge tuple and integral instances into tuple of references
我在尝试从元组和整数值的混合构造引用元组时遇到了奇怪的行为。
鉴于以下情况:
struct A { int v = 1; };
struct B { int v = 2; };
struct C { int v = 3; };
A a;
std::tuple<B,C> tpl;
我正在尝试创建第三个元组,其中包含对所有实例的引用,以便每个实例的v
都可以通过它进行分配和读取。
使用模板似乎很简单
template <class Tuple, size_t... Is>
constexpr auto as_ref_impl(Tuple t, std::index_sequence<Is...>) {
return std::tuple_cat(std::tie(std::get<Is>(t))...);
// or
// return std::make_tuple(std::ref(std::get<Is>(t))...);
}
template <class...Args>
constexpr auto as_ref(std::tuple<Args...>& t) {
return as_ref_impl(t, std::index_sequence_for<Args...>{});
}
然后
auto ref_tpl = std::tuple_cat(std::tie(a), as_ref(tpl));
构建良好(在两个版本中(。
不幸的是,只有引用元组(ref_tpl
(中源自整数值的部分才能被成功赋值或读取。
我正在使用C++14
和gcc 9.3.0
.
非常欢迎任何想法或见解,为什么这不起作用!
最小工作示例:
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
#include <functional>
struct A { int v = 1; };
struct B { int v = 2; };
struct C { int v = 3; };
A a;
std::tuple<B,C> tpl;
template <class Tuple, size_t... Is>
constexpr auto as_ref_impl(Tuple t, std::index_sequence<Is...>) {
//return std::tuple_cat(std::tie(std::get<Is>(t))...);
return std::make_tuple(std::ref(std::get<Is>(t))...);
}
template <class...Args>
constexpr auto as_ref(std::tuple<Args...>& t) {
return as_ref_impl(t, std::index_sequence_for<Args...>{});
}
int main() {
using std::cout;
auto ref_tpl = std::tuple_cat(std::tie(a), as_ref(tpl));
// prints 1 2 3, as expected.
cout << a.v << std::get<0>(tpl).v << std::get<1>(tpl).v << std::endl;
std::get<0>(ref_tpl).v = 8; // works
std::get<1>(ref_tpl).v = 9; // does not work
std::get<2>(ref_tpl).v = 10; // does not work
// should output 8 9 10 instead outputs 8 2 3
cout << a.v << std::get<0>(tpl).v << std::get<1>(tpl).v << std::endl;
// should output 8 9 10, instead outputs garbage.
cout << std::get<0>(ref_tpl).v << std::get<1>(ref_tpl).v << std::get<2>(ref_tpl).v << std::endl;
return 0;
}
这是一个简单的错别字:
constexpr auto as_ref_impl(Tuple t, std::index_sequence<Is...>) {
Tuple
是按值获取的,因此会创建本地副本,并相对于它进行引用。
您应该通过引用来获取Tuple
,
constexpr auto as_ref_impl(Tuple& t, std::index_sequence<Is...>) {
您的as_ref_impl
需要通过引用获取Tuple
参数,否则您将std::ref
函数本地。这解释了tpl
的未修改值,以及ref_tpl
中的垃圾值。
请改为执行以下操作:
template <class Tuple, size_t... Is>
// note the reference parameter
constexpr auto as_ref_impl(Tuple &t, std::index_sequence<Is...>) {
return std::make_tuple(std::ref(std::get<Is>(t))...);
}
这是一个演示。
相关文章:
- 返回两个向量 – 使用引用还是元组?
- 将元组和整型实例合并到引用元组中
- 在SESHAT中,对"元组"的引用是模棱两可的
- 为什么此元组到引用元组 (std::tie) 转换有效?
- 如何从参数包构造引用的 std::元组?
- 使用单参数模板化构造函数,从引用元组构造值元组
- 结构化绑定和引用元组
- 获取对元组元素的引用
- 创建对满足特定谓词的对象的引用元组
- 使用对另一个元组不同类型的元素的非常量引用来初始化元组的元素
- 为引用元组赋值
- 如何从对象中获取对元组尾部的引用 std::tuple<Head,Tail...>
- C++:使用引用和值解压缩元组,而无需复制/移动太多
- 将一包转发引用包装成元组
- 如何编写对转发的引用元组进行操作的constexpr函数
- 有没有办法在函数以编程方式返回的引用上多次调用函数? -元组动态访问
- c++存储映射元组的引用,以便在另一个函数中使用
- 有没有一种方法可以将左值和右值的列表分别转换为具有引用类型和完整类型的元组
- 引用折叠和元组
- 如何从一个值元组中生成一个左值元组引用