提问人:Ragdoll Car 提问时间:7/10/2023 最后编辑:Ragdoll Car 更新时间:7/13/2023 访问量:88
解压缩可变参数模板以initializer_list并同时调用两个函数
Unpack variadic template to initializer_list and call two functions at once
问:
我有两个向量:
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 4, 5, 6 };
我想创建一个对象,该对象包含上述向量的第一个和最后一个元素的迭代器。std::initializer_list
我想要一个带有可变参数模板的函数:
template<class... Ts>
void foo(Ts... args)
在上面的函数中,我想解压缩所有参数。到目前为止,我实现了:
template<class... Ts>
void foo(Ts... args)
{
std::initializer_list<std::vector<int>::iterator> il{
(std::begin(args), std::end(args))...
};
}
int main()
{
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 4, 5, 6 };
foo(v1, v2);
}
但由于 .当前实现使用两个迭代器创建。在这种情况下,我想要的是有一个 4 个迭代器指向这两个向量的第一个和一个指向结束元素的迭代器。我希望它是 , , , .operator,
initializer_list
initializer_list
begin
end
begin
end
答:
4赞
Ted Lyngmo
7/10/2023
#1
我认为你最好的办法是以 s 的形式添加迭代器:std::pair
template<class... Ts>
void foo(Ts... args) {
std::initializer_list<std::pair<std::vector<int>::iterator,
std::vector<int>::iterator>> il
{
{std::begin(args), std::end(args)}...
};
}
现在,这将有两个带有 和 迭代器的 s,即总共 4 个迭代器。initializer_list
std::pair
begin()
end()
评论
0赞
Ragdoll Car
7/10/2023
这是一个很好的答案,但不幸的是,我不能在我的.是否有可能在内部没有嵌套类型的情况下做到这一点?std::pair
std::initializer_list
std::initializer_list
1赞
Ted Lyngmo
7/10/2023
@RagdollCar嗯,我需要考虑一下:-)
6赞
Jarod42
7/10/2023
#2
您可以创建数组而不是:initializer_list
template<class... Ts>
auto foo(Ts&... args)
{
std::array<typename std::common_type_t<std::decay_t<Ts>...>::iterator, 2 * sizeof...(Ts)> res;
std::size_t i = 0;
((res[i++] = args.begin(), res[i++] = args.end()), ...);
return res;
}
4赞
Artyer
7/10/2023
#3
您可以制作一个长度增加一倍的新包:
#include <vector>
#include <utility>
#include <tuple>
namespace detail {
template<std::size_t... I, class... Ts>
void foo_impl(std::index_sequence<I...>, Ts&... args) {
std::initializer_list<std::vector<int>::iterator> il{
[&]() -> std::vector<int>::iterator {
auto& vec = std::get<I/2u>(std::tie(args...));
return I % 2u == 0u ? std::begin(vec) : std::end(vec);
}()...
};
// ...
}
}
template<class... Ts>
void foo(Ts... args) {
return detail::foo_impl(std::make_index_sequence<sizeof...(args)*2u>{}, args...);
}
或者考虑您是否需要。您也许可以使用数组:initializer_list
template<class... Ts>
void foo(Ts... args) {
std::vector<int>::iterator il[sizeof...(args)*2u];
{
auto* p = std::begin(il);
(((*p++ = std::begin(args)), (*p++ = std::end(args))), ...);
}
// ...
}
评论
0赞
Ragdoll Car
7/10/2023
就是这样!谢谢!
评论
begin, end, begin, end
begin, begin, end, end
std::vector<int>
std::initializer_list<std::reference_wrapper<std::vector<int>>>