文章目录
-
- tuple的使用
- 遍历tuple
- 模板函数中使用tuple保存函数参数
tuple属于C++11标准库函数的一部分,常用于接收不定参数。需要理解以下关键字和模板,以便理解后面的例子。
- decltype的作用是获取变量的类型
- typename的作用是声明后面的部分属于类型,因为在模板中是不知道它是类型还是变量的
- remove_reference的作用是如果是引用类型只保留类型
tuple的使用
make_tuple用于构造一个tuple、tuple_size用于获取tuple的参数个数、get获取tuple指定索引的值
- get(tuple)中的n必须是一个在编译时可以确定的常量或常量表达式,所以如果要依次获取tuple内的值,我们需要一个可变参数模板函数参数
std::tuple<double, char, std::string> t = std::make_tuple(3.14, 'A', "StoneLiu");
std::cout << "tuple length " << std::tuple_size<decltype(t)>::value;
std::cout << "first: " << std::get<0>(t) << ", two: " << std::get<1>(t) << ", three: " << std::get<2>(t) ;
遍历tuple
// 帮助程序用于将元组转换为可变参数模板函数参数
// sequence_generator<3>::type will be sequence<0, 1, 2>.
template <int...>
struct sequence {};
template <int N, int... S>
struct sequence_generator : sequence_generator<N - 1, N - 1, S...> {};
template <int... S>
struct sequence_generator<0, S...> {
typedef sequence<S...> type;
};
template<typename T, typename F, int... S>
void for_each(T&& t, F f, sequence<S...>)
{
auto l = { (f(std::get<S>(t)), 0)... };
}
template<typename... Args, typename F>
void for_each_in_tuple(std::tuple<Args...> const& t, F f)
{
for_each(t, f, typename sequence_generator<sizeof...(Args)>::type());
}
struct functor {
template<typename T>
void operator()(T&& t)
{
std::cout << t << std::endl;
}
};
int main()
{
std::tuple<double, char, std::string> t = std::make_tuple(3.14, 'A', "StoneLiu");
for_each_in_tuple(t, functor());
}
模板函数中使用tuple保存函数参数
这些参数在构造方法本身的时候已经确定了,封装这样的一个模板方法主要用于WebRTC里面的跨线程调用
// 帮助程序用于将元组转换为可变参数模板函数参数
// sequence_generator<3>::type will be sequence<0, 1, 2>.
template <int...>
struct sequence {};
template <int N, int... S>
struct sequence_generator : sequence_generator<N - 1, N - 1, S...> {};
template <int... S>
struct sequence_generator<0, S...> {
typedef sequence<S...> type;
};
// The following code comes from WebRTC rtc_base bind.h
// 此结构体的功能是用于封装一个方法
template <class ObjectT, class MethodT, class R, typename... Args>
class MethodFunctor {
public:
// 我们在构造这个方法的时候可以传递不定参数,这些参数保存在args_中
MethodFunctor(MethodT method, ObjectT* object, Args... args)
: method_(method), object_(object), args_(args...) {}
// 当我们调用()方法的时候,我们从args_中把参数依次取出来调用
R operator()() const {
return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
}
private:
// Use sequence_generator (see template_util.h) to expand a MethodFunctor
// with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for instance.
// S的值就类似[0, 1, 2, 3 ...],使用模板依次取出所有的参数传递给method_
template <int... S>
R CallMethod(sequence<S...>) const {
return (object_->*method_)(std::get<S>(args_)...);
}
MethodT method_;
typename detail::PointerType<ObjectT>::type object_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};