如何将std :: vector转换为args

时间:2017-02-01 13:21:41

标签: c++ vector variadic-functions

我有一个函数,它接受多个这样的参数:

void test(const auto&...args)
{
   typedef boost::variant<int, float, std::string> Variant;
   std::vector<Variant> vec = {args...}
}

这很好 - 根据Variant

,参数在向量内部作为不同的类型

我想从类似的向量中获取参数并将其放回到一个带有args的函数中......

类似的东西:

args = vec;
test2(args);

void test2(const auto&...args);

怎么办呢?

3 个答案:

答案 0 :(得分:3)

不,这是不可能的。必须在编译时确定参数包,以便进行扩展。每个唯一类型的参数包都成为它自己的唯一函数调用,在编译时创建。

显然,直到运行时才知道向量的大小。从根本上说,C ++不能像那样工作。

答案 1 :(得分:3)

可以这样做。但由于向量的大小仅在运行时已知,因此不匹配大小的错误也必须在运行时发生。

我是这样做的:

template<std::size_t... S>
void unpack_vector(const std::vector<Variant>& vec, std::index_sequence<S...>) {
    test2(vec[S]...);
}

template<std::size_t size>
void unpack_vector(const std::vector<Variant>& vec) {
    if (vec.size() != size) throw /* choose your error */;
    unpack_vector(vec, std::make_index_sequence<size>());
}

然后你可以这样称呼它:

unpack_vector<6>(vec);

请注意,此函数会将Variant个实例发送到函数test2

我必须承认这可能是一个坏主意,运行时错误并不是最好的。我建议你检查你的设计,以便不需要这个。

答案 2 :(得分:1)

根据@Guillaume Racicot的回答,我找到了这个解决方案(来自http://en.cppreference.com/w/cpp/utility/integer_sequence的代码段):

此示例显示如何将std :: tuple转换为函数调用的参数。

#include <iostream>
#include <tuple>
#include <utility>

template<typename Func, typename Tup, std::size_t... index>
decltype(auto) invoke_helper(Func&& func, Tup&& tup, std::index_sequence<index...>)
{
    return func(std::get<index>(std::forward<Tup>(tup))...);
}

template<typename Func, typename Tup>
decltype(auto) invoke(Func&& func, Tup&& tup)
{
    constexpr auto Size = std::tuple_size<typename std::decay<Tup>::type>::value;
    return invoke_helper(std::forward<Func>(func),
                         std::forward<Tup>(tup),
                         std::make_index_sequence<Size>{});
}

void foo(int a, const std::string& b, float c)
{
    std::cout << a << " , " << b << " , " << c << '\n';
}

int main()
{
    auto args = std::make_tuple(2, "Hello", 3.5);
    invoke(foo, args);
}

输出:

2,你好,3.5