-
Notifications
You must be signed in to change notification settings - Fork 77
How to unpack a std::tuple to a function with multiple arguments?
Haojian Wu edited this page Aug 17, 2017
·
1 revision
How to unpack a std::tuple to match a call function with multiple arguments?
Given the following example:
template<typename... Args>
void f(Args... args) {
...
}
void t() {
std::tuple<int, int, double> t;
// A ordinal way.
f(std::get<0>(t), std::get<1>(t), std::get<2>(t));
// But what if a tuple of 4 elements?
// Is there a generic way to do the job automatically?
// But how to to match a generic std::tuple<Args...> to f(Args...)?
// is there a automatic way to do it? See answer below:
invoke(tuple, index_sequence_for<tuple>);
}
template<typename Tuple, typename size_t...I>
void invoke(const Tuple& args, index_sequence<I...>) {
f(std::get<I>(args)...);
}
The solution is to use the well-known "indices trick" — bascally generate a compile-time integer sequence representing the indices of std::tuple, which means (0, std::tuple.size() -1], and use the index to access the elements from the tuple.
- C++14 has provided utility templates (e.g.
make_index_seqence
,index_sequence_for
) which helps us do this stuff. - Prior to C++14, we have to implement by our own. Fortunately, the implementation is not complicated, only a few lines of code. In many codebases, they have their own implementation.
LLVM has provided a fully standard implementation:
// Represents a compile-time sequence of integers.
// T is the integer type of the sequence, can be size_t, int.
// I is a parameter pack representing the sequence.
template <class T, T... I> struct integer_sequence {
typedef T value_type;
static constexpr size_t size() { return sizeof...(I); }
};
// Alias for the common case of a sequence of size_t.
// A pre-defined sequence for common use case.
template <std::size_t... I>
struct index_sequence : integer_sequence<std::size_t, I...> {};
template <std::size_t N, std::size_t... I>
struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
template <std::size_t... I>
struct build_index_impl<0, I...> : index_sequence<I...> {};
// Creates a compile-time integer sequence for a parameter pack.
template <class... Ts>
struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
Chromium has provide a simpler implementation of compile-time integer indices:
template <size_t... indices>
struct IndicesHolder {};
// Usage: IndicesGenerator<N>::type
template <size_t requested_index, size_t... indices>
struct IndicesGenerator {
using type = typename IndicesGenerator<requested_index - 1,
requested_index - 1,
indices...>::type;
};
template <size_t... indices>
struct IndicesGenerator<0, indices...> {
using type = IndicesHolder<indices...>;
};
LLVM/Clang
C/C++
- Get lower 32 bits from uint64
- How to unpack a std::tuple to a function with multiple arguments?
- {}-list Initialization
- Empty macro arguments
- 为什么能在函数中以by value方式返回unique_ptr?
- c++unsigned类型提升
- extern "C"
Linux
- ubuntu获取源码方法
- gcc/g++常用命令
- 浏览器导入安全证书
- ubuntu下宏包latex安装
- Bash Shell常用快捷键
- ubuntu把/tmp目录挂载到内存
- tar命令
- voyager12.04 apt-get install无法安装解决方法
- terminal shows git branch
- 编译GTK API源程序(附带pkg-config用法)
- ldconfig检查库是否存在
- Googletest Setup&Install
- Centos设置service开机自动启动
- CentOS create admin user
- 设置时区
- MySQL修改root密码
- MySQL常用命令
- Screen使用
- 环境变量
- Unity桌面环境的desktop文件
- zip和gzip文件区别
- Linux安全设置
Vim
- vim列编辑
- vim编辑二进制文件
- vim quickfix窗口
- Vim 批量操作
- Vim对多行重复操作
- mac下vim编译安装
- mac下vim taglist无效解决方法
- Vim 配置vim-airline
Tools
- gdb cgdb命令
- Source Insight添加.cc文件
- Source Insight快捷键
- GPT分区转MBR分区
- IRC工具Pidgin使用
- iTerm2 shortcuts
- MacOS shortcuts
- Compile/Run JUnitTest in Command Line
- Install Python2.7 on CentOS 6.4
- Install vmware tool on ubuntu server 12.04
- node-gyp Usage
- zsh中文乱码解决方法
- tmux快捷键
- 使用aria2突破百度云盘限速
- 配置 scheme编写环境
- How to list all available targets in ninja
Others
- CRLF换行符
- Git autocrlf设置
- Git reflog数据恢复命令
- how to migrate from SVN repo to Git repo
- Git submodule使用
- Git Pull强制更新
Chromium-Dev tips