7co*_*ows 37 c++ templates tuples c++11
我的问题在于代码:
template<typename... Ts>
struct TupleOfVectors {
std::tuple<std::vector<Ts>...> tuple;
void do_something_to_each_vec() {
//Question: I want to do this:
// "for each (N)": do_something_to_vec<N>()
//How?
}
template<size_t N>
void do_something_to_vec() {
auto &vec = std::get<N>(tuple);
//do something to vec
}
};
Run Code Online (Sandbox Code Playgroud)
And*_*owl 34
你可以很容易地用一些指数机制做到这一点.给定gen_seq
用于生成编译时整数序列的元函数(由seq
类模板封装):
namespace detail
{
template<int... Is>
struct seq { };
template<int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
template<int... Is>
struct gen_seq<0, Is...> : seq<Is...> { };
}
Run Code Online (Sandbox Code Playgroud)
以及以下功能模板:
#include <tuple>
namespace detail
{
template<typename T, typename F, int... Is>
void for_each(T&& t, F f, seq<Is...>)
{
auto l = { (f(std::get<Is>(t)), 0)... };
}
}
template<typename... Ts, typename F>
void for_each_in_tuple(std::tuple<Ts...> const& t, F f)
{
detail::for_each(t, f, detail::gen_seq<sizeof...(Ts)>());
}
Run Code Online (Sandbox Code Playgroud)
您可以使用for_each_in_tuple
以上方式的功能:
#include <string>
#include <iostream>
struct my_functor
{
template<typename T>
void operator () (T&& t)
{
std::cout << t << std::endl;
}
};
int main()
{
std::tuple<int, double, std::string> t(42, 3.14, "Hello World!");
for_each_in_tuple(t, my_functor());
}
Run Code Online (Sandbox Code Playgroud)
这是一个实例.
在具体情况下,您可以使用它:
template<typename... Ts>
struct TupleOfVectors
{
std::tuple<std::vector<Ts>...> t;
void do_something_to_each_vec()
{
for_each_in_tuple(t, tuple_vector_functor());
}
struct tuple_vector_functor
{
template<typename T>
void operator () (T const &v)
{
// Do something on the argument vector...
}
};
};
Run Code Online (Sandbox Code Playgroud)
再一次,这是一个现实的例子.
M. *_*gan 29
在C++ 17中,您可以这样做:
std::apply([](auto ...x){std::make_tuple(some_function(x)...);} , the_tuple);
Run Code Online (Sandbox Code Playgroud)
鉴于some_function
对元组中的所有类型都有适当的重载.
这已经在Clang ++ 3.9中使用了std::experimental::apply
.
Dev*_*ull 15
除了@M 的答案.Alaggan,如果你需要在元组中按顺序调用元组元素,在C++ 17中你也可以使用这样的fold表达式:
std::apply([](auto& ...x){(..., some_function(x));}, the_tuple);
Run Code Online (Sandbox Code Playgroud)
(现场例子).
这是一种可能适用于您的情况的方法:
template<typename... Ts>
struct TupleOfVectors {
std::tuple<std::vector<Ts>...> tuple;
void do_something_to_each_vec()
{
// First template parameter is just a dummy.
do_something_to_each_vec_helper<0,Ts...>();
}
template<size_t N>
void do_something_to_vec()
{
auto &vec = std::get<N>(tuple);
//do something to vec
}
private:
// Anchor for the recursion
template <int>
void do_something_to_each_vec_helper() { }
// Execute the function for each template argument.
template <int,typename Arg,typename...Args>
void do_something_to_each_vec_helper()
{
do_something_to_each_vec_helper<0,Args...>();
do_something_to_vec<sizeof...(Args)>();
}
};
Run Code Online (Sandbox Code Playgroud)
这里唯一有点乱的是额外的虚拟int
模板参数do_something_to_each_vec_helper
.当没有参数保留时,必须使do_something_to_each_vec_helper仍然是模板.如果您想要使用另一个模板参数,则可以在那里使用它.
如果您不是特别坚持使用通用"for each"功能模板形式的解决方案,那么您可以使用如下所示:
#ifndef TUPLE_OF_VECTORS_H
#define TUPLE_OF_VECTORS_H
#include <vector>
#include <tuple>
#include <iostream>
template<typename... Ts>
struct TupleOfVectors
{
std::tuple<std::vector<Ts>...> tuple;
template<typename ...Args>
TupleOfVectors(Args... args)
: tuple(args...){}
void do_something_to_each_vec() {
do_something_to_vec(tuple);
}
template<size_t I = 0, class ...P>
typename std::enable_if<I == sizeof...(P)>::type
do_something_to_vec(std::tuple<P...> &) {}
template<size_t I = 0, class ...P>
typename std::enable_if<I < sizeof...(P)>::type
do_something_to_vec(std::tuple<P...> & parts) {
auto & part = std::get<I>(tuple);
// Doing something...
std::cout << "vector[" << I << "][0] = " << part[0] << std::endl;
do_something_to_vec<I + 1>(parts);
}
};
#endif // EOF
Run Code Online (Sandbox Code Playgroud)
使用GCC 4.7.2和clang 3.2构建的测试程序:
#include "tuple_of_vectors.h"
using namespace std;
int main()
{
TupleOfVectors<int,int,int,int> vecs(vector<int>(1,1),
vector<int>(2,2),
vector<int>(3,3),
vector<int>(4,4));
vecs.do_something_to_each_vec();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
相同的递归样式可以在没有辅助索引装置的通用"for_each"函数模板中使用:
#ifndef FOR_EACH_IN_TUPLE_H
#define FOR_EACH_IN_TUPLE_H
#include <type_traits>
#include <tuple>
#include <cstddef>
template<size_t I = 0, typename Func, typename ...Ts>
typename std::enable_if<I == sizeof...(Ts)>::type
for_each_in_tuple(std::tuple<Ts...> &, Func) {}
template<size_t I = 0, typename Func, typename ...Ts>
typename std::enable_if<I < sizeof...(Ts)>::type
for_each_in_tuple(std::tuple<Ts...> & tpl, Func func)
{
func(std::get<I>(tpl));
for_each_in_tuple<I + 1>(tpl,func);
}
#endif //EOF
Run Code Online (Sandbox Code Playgroud)
并为此测试程序:
#include "for_each_in_tuple.h"
#include <iostream>
struct functor
{
template<typename T>
void operator () (T&& t)
{
std::cout << t << std::endl;
}
};
int main()
{
auto tpl = std::make_tuple(1,2.0,"Three");
for_each_in_tuple(tpl,functor());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
20575 次 |
最近记录: |