我有一个函数,它接受多个参数,如下所示:
void test(const auto&...args)
{
typedef boost::variant<int, float, std::string> Variant;
std::vector<Variant> vec = {args...}
}
这工作正常 - 参数在向量内根据变体作为不同类型的不同类型
我想从类似的向量中获取参数并将其放回一个接受参数的函数中......
像这样:
args = vec;
test2(args);
void test2(const auto&...args);
怎么能做到这一点?
可以这样做。但是,由于矢量的大小仅在运行时已知,因此大小不匹配的错误也必须在运行时发生。
以下是我的做法:
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
。
我必须承认这可能是一个坏主意,运行时错误不是最好的。我建议你检查你的设计,以便不需要这个。
不,这是不可能的。参数包必须在编译时确定,以便进行扩展。每个唯一类型的参数包都成为其自己唯一的函数调用,在编译时创建。
显然,向量的大小直到运行时才知道。从根本上说,C++不是那样工作的。
基于@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