C++11: 如何编写一个像 Get 一样工作的模板函数<tuple>...但是收到参数包?
C++11: how to write a template function that works like get<tuple>... but receives param pack?
我知道在 c++11 中,get<> 模板函数与 std::tuple 一起使用以获取元组的索引值,这在编译时解决。
但我的要求是有一个名为get的模板函数<>但接收一个参数包,所以代码应该如下所示:
#include<iostream>
using namespace std;
template<typename Head, typename ... Tail>
auto get(size_t index, Head&& t, Tail&&...tail){
return get(index-1, tail...);
}
template<typename Head, typename ... Tail>
Head get<0>(Head&& t, Tail&&...tail){
return t;
}
int main(){
cout<<get(3,"abc",'x',27,"hello")<<endl;
cout<<get(2,"abc",'x',28,"hello")<<endl;
return 0;
}
好吧,它肯定不会编译,因为我不知道如何编写这样的"get"模板函数。我希望主函数将运行并打印如下:
hello
28
所以我的问题:如何实现我上面提到的这个"获取"模板? 谢谢!
你真的需要能够在运行时选择索引吗?如果没有,以下内容就足够了:
template <std::size_t Index, typename ...P> auto get(P &&... params)
{
return std::get<Index>(std::make_tuple(params...));
}
// ...
std::cout << get<1>("abc", 42, 123.456); // Prints 42
如果您确实希望将索引作为普通(运行时(参数,则必须返回std::variant<P...>
(或std::any
或标记的联合(,因为返回类型不能依赖于运行时参数。
可能的实现可能如下所示:
template <typename ...P> std::variant<P...> get(std::size_t index, P &&... params)
{
std::size_t pos = 0;
std::variant<P...> ret;
((index == pos++ ? void(ret = params) : void()) , ...);
return ret;
}
// ...
std::cout << std::get<int>( get(1, "abc", 42, 123.456) ); // Prints 42 too, but looks ugly
或者,您可以将返回类型指定为模板参数:
template <typename T, typename ...P> T get(std::size_t index, P &&... params)
{
std::size_t pos = 0;
std::variant<P...> va;
((index == pos++ ? void(va = params) : void()) , ...);
if (T *ptr = std::get_if<T>(va))
return T;
else
throw /*something*/;
}
// ...
std::cout << get<int>(1, "abc", 42, 123.456); // 42
或者您可以将值传递给函数/函子:(谢谢@Yakk(
template <typename T, typename ...P> void get(std::size_t index, T &&func, P &&... params)
{
std::size_t pos = 0;
((index == pos++ ? void(func(params)) : void()) , ...);
}
// ...
get(1, [](int x){std::cout << x;}, "abc", 42, 123.456); // 42
// Alternative:
// get(1, [](auto x){std::cout << x;}, "abc", 42, 123.456); // 42 too,
// but you could print any type which can be printed without having to
// specify the type manually.
相关文章:
- Cpp-Tuple使用带有变量的get
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 为什么我不能在 constexpr lambda 函数中使用 std::tuple
- 在 std::tuple 上使用 std::variant 的问题
- 在构造函数中使用可变参数初始化 std::tuple
- 将"boost::tuple "转换为"boost::fusion::tuple&quo
- 转发复制的 std::tuple
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- std::tuple 可以根据其值在编译时/运行时排序吗?
- 返回 std::tuple 中的引用和值
- 如何将 boost::hana::tuple 转换为 std::变体
- 如何从可变参数模板参数创建 std::tuple<>?
- std::tuple 的自定义哈希不适用于unordered_set
- 为什么基于 int 的访问不适用于 std::get(std::tuple)?
- 带有引用的std::tuple在clang中编译失败,但在gcc中编译失败
- 如何显式调用运算符<<
- 尝试实现std::tie和std::tuple的小版本