如何通过索引从可变参数模板参数包中提取值?

xml*_*lmx 4 c++ templates compile-time-constant variadic-templates c++11

我想编写一个函数magic_get,它可以通过索引从参数包中提取值,例如:

int n = 0;
n = magic_get<0>(1, 3, 5, 7);
assert(1 == n);
n = magic_get<1>(1, 3, 5, 7);
assert(3 == n);
n = magic_get<2>(1, 3, 5, 7);
assert(5 == n);
n = magic_get<3>(1, 3, 5, 7);
assert(7 == n);
Run Code Online (Sandbox Code Playgroud)

如何实施magic_get

T.C*_*.C. 14

template <size_t N, typename... Args>
decltype(auto) magic_get(Args&&... as) noexcept {
    return std::get<N>(std::forward_as_tuple(std::forward<Args>(as)...));
}
Run Code Online (Sandbox Code Playgroud)

改变decltype(auto)auto与添加的尾返回类型decltype(/* the whole returned expression here */),如果C++ 14个功能不可用.


无元版:

template <std::size_t N, typename Tfirst, typename... Args, std::enable_if_t<N == 0, int>...>
decltype(auto) magic_get(Tfirst&& first, Args&&... as) noexcept {
    return std::forward<Tfirst>(first);
}

template <std::size_t N, typename Tfirst, typename... Args, std::enable_if_t<N != 0, int>...>
decltype(auto) magic_get(Tfirst&& first, Args&&... as) noexcept {
    return magic_get<N - 1>(std::forward<Args>(as)...);
}
Run Code Online (Sandbox Code Playgroud)

请注意,由于clang bug 11723,这在clang中不起作用.更换std::enable_if_t<N != 0, int>...std::enable_if_t<N != 0, int> = 0是一个简单的解决方法.

  • @xmllmx是的,这是可能的,但为什么重新发明轮子?优化器将优化所有内容,因为元组是一个引用元组,因此它的析构函数是微不足道的. (3认同)