使用 std::vector 中的参数调用可变参数模板函数
Call variadic templated function with arguments from a std::vector
我需要将 std::vector 的元素转换为基于模板参数的类型,并使用这些参数调用函数。在伪代码中:
template <typename T...>
void foo(std::vector<std::string> v) {
if (v.size() != sizeof...(T))
throw std::runtime_error("Bad");
bar(convert<T0>(v[0]), convert<T1>(v[1]), ..., convert<Tn>(v[n]));
}
我的问题是如何从参数包中获取元素索引,我认为使用折叠表达式会有某种技巧,但我想不通。
如果知道向量中的元素个数等于参数包的大小,就可以通过增加一层间接来解决这个问题:
template<typename... T, std::size_t... is>
void foo_impl(const std::vector<std::string>& v, std::index_sequence<is...>) {
bar(convert<T>(v[is])...);
}
template<typename... T>
void foo(const std::vector<std::string>& v) {
assert(v.size() == sizeof...(T));
foo_impl<T...>(v, std::index_sequence_for<T...>{});
}
这里的想法是同时展开大小相等的两个包 Ts...
和 is...
。
C++20 解决方案:
template<typename... T>
void foo(const std::vector<std::string>& v) {
assert(v.size() == sizeof...(T));
[&v]<std::size_t... is>(std::index_sequence<is...>) {
bar(convert<T>(v[is])...);
}(std::index_sequence_for<T...>{});
}
您可以通过使用 std::integer_sequence
访问向量的元素来解决这个问题。
namespace detail
{
template <typename...T, size_t...I>
void foo(std::vector<std::string>& v, std::index_sequence<I...>) {
bar(convert<T>(v[I])...);
}
}
template <typename...T>
void foo(std::vector<std::string>& v) {
if (v.size() != sizeof...(T))
throw std::runtime_error("Bad");
detail::foo<T...>(v, std::index_sequence_for<T...>{});
}
关于神马:Link
我需要将 std::vector 的元素转换为基于模板参数的类型,并使用这些参数调用函数。在伪代码中:
template <typename T...>
void foo(std::vector<std::string> v) {
if (v.size() != sizeof...(T))
throw std::runtime_error("Bad");
bar(convert<T0>(v[0]), convert<T1>(v[1]), ..., convert<Tn>(v[n]));
}
我的问题是如何从参数包中获取元素索引,我认为使用折叠表达式会有某种技巧,但我想不通。
如果知道向量中的元素个数等于参数包的大小,就可以通过增加一层间接来解决这个问题:
template<typename... T, std::size_t... is>
void foo_impl(const std::vector<std::string>& v, std::index_sequence<is...>) {
bar(convert<T>(v[is])...);
}
template<typename... T>
void foo(const std::vector<std::string>& v) {
assert(v.size() == sizeof...(T));
foo_impl<T...>(v, std::index_sequence_for<T...>{});
}
这里的想法是同时展开大小相等的两个包 Ts...
和 is...
。
C++20 解决方案:
template<typename... T>
void foo(const std::vector<std::string>& v) {
assert(v.size() == sizeof...(T));
[&v]<std::size_t... is>(std::index_sequence<is...>) {
bar(convert<T>(v[is])...);
}(std::index_sequence_for<T...>{});
}
您可以通过使用 std::integer_sequence
访问向量的元素来解决这个问题。
namespace detail
{
template <typename...T, size_t...I>
void foo(std::vector<std::string>& v, std::index_sequence<I...>) {
bar(convert<T>(v[I])...);
}
}
template <typename...T>
void foo(std::vector<std::string>& v) {
if (v.size() != sizeof...(T))
throw std::runtime_error("Bad");
detail::foo<T...>(v, std::index_sequence_for<T...>{});
}
关于神马:Link