从std::tuple成员中移除引用

5
我正在使用STL元组实现一些变量的保存/恢复功能,具体如下:

double a = 1, b = 2;
int c = 3;
auto tupleRef = std::make_tuple(std::ref(a), std::ref(b), std::ref(c));

// here I'm saving current state of a, b, c
std::tuple<double, double, int> saved = tupleRef;

//here goes block of code, where a, b, and c get spoiled
......................
//

//now I'm restoring initial state of a, b, c
tupleRef = savedTuple;

这段代码运行良好。但是,与其在元组成员中显式指定类型,更好的方法是使用“类型提示”。
std::tuple<double, double, int> saved = tupleRef;

我希望您能够将所有tupleRef成员的引用移除,例如以下所示。
auto saved = remove_ref_from_tuple_members(tupleRef);

我相信可以编写“remove_ref_from_tuple_members”模板来实现这一目的。

感谢回答。

2个回答

7

可以使用简单的类型别名将std :: remove_reference应用于元组中的所有类型。

template <typename... T>
using tuple_with_removed_refs = std::tuple<typename std::remove_reference<T>::type...>;

有了这个,你现在可以编写函数模板:

template <typename... T>
tuple_with_removed_refs remove_ref_from_tuple_members(std::tuple<T...> const& t) {
    return tuple_with_removed_refs { t };
}

2
等等,你的意思是模板参数包有内置的“映射”操作(在函数式编程意义上,而不是std::map的意义)?赞美上帝,我竟然能够看到这样的时代! - Steve Jessop
@SteveJessop 是的,我认为你可以这么说。你可以将一个包扩展到任何模式中。 - R. Martinho Fernandes
感谢您的回答。我相信它有效,至少看起来很合理。不幸的是,可变参数模板在我的电脑上无法编译,无论是在Visual Studio 2010还是VS2012中,它们都不受VS支持。看起来他们硬编码了元组最多只能有15个成员。 - Alex B.
为了修复它,我必须将第二个函数中的tuple_with_removed_refs的两个实例都更改为tuple_with_removed_refs <T ...> - M.M

0
感谢 R. Martinho Fernandes 的代码,我能够修改它以在 Visual Studio 中编译,其中 tuple 被硬编码为一个带有 10 种类型的模板,未使用的类型为空结构体。
#define _RR_(x) typename std::remove_reference<x>::type
#define _no_ref_tuple_  std::tuple<_RR_(T0), _RR_(T1), _RR_(T2), _RR_(T3), _RR_(T4), _RR_(T5), _RR_(T6), _RR_(T7), _RR_(T8), _RR_(T9)>

template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
_no_ref_tuple_ map_remove_ref(std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> const& t) 
{
    return _no_ref_tuple_(t);
}

我也认为将引用绑定到元组中,就像...

auto tupleRef = std::make_tuple(std::ref(x_0), ..., std::ref(x_n));

可以变得更加简洁:

auto tupleRef = std::forward_as_tuple(x_0, ..., x_n);

但这在 VS 中仍然无法工作,因为没有 std::forward_as_tuple。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接