[英]How to have template type deduced in std::function arguments with lambda?
[英]How to pass a std::pair of iterators to a function template and have the iterator types deduced?
我试图将两个迭代器包装成一个 std::pair 并将其传递给一个函数参数,但希望迭代器的类型是通用的。
这对本身在迭代器类型上进行了模板化......
template<typename Iterator>
using iteratorPair = std::pair<Iterator,Iterator>;
...然后模板函数本身具有签名...
template<typename T, typename U,template<typename> class IteratorPair, template<typename> class IteratorPairInt>
void
sortUsingIndicesToTargetContainerPair(
const IteratorPair<T>& rangeToSortSource,
const IteratorPair<T>& rangeToSortTarget,
const IteratorPairInt<U>& indicesRange)
{ ...}
我正在做所有这些,以便我可以通过钎焊初始化调用该函数......
std::vector<int> vecs{0,1,2,3,4,5,6,7,8,9};
std::vector<int> indices{9,8,7,6,5,4,3,2,1,0};
auto copy = vecs;
sortUsingIndicesToTargetContainerPair({vecs.begin(), vecs.end()},
{copy.begin(), copy.end()},
{indices.begin(), indices.end()});
如果我在调用函数时使用它的名称显式构造类型,我可以让它工作,但如果可能的话,我想使用花括号初始化。
任何帮助,将不胜感激! 谢谢
我可以建议下面的解决方案。 想法:不要尝试直接推导类型,而是添加一个适配器函数,将参数数组转换为迭代器对:
template<typename T, typename TIndex, std::size_t N>
constexpr void FAdaptor
(
const T(&rangeToSortSource)[N],
const T(&rangeToSortTarget)[N],
const TIndex(&indicesRange)[N]
)
{
static_assert(2 == N, "must be pair");
sortUsingIndicesToTargetContainerPair
(
IteratorPair<T>(rangeToSortSource[0], rangeToSortSource[1]),
IteratorPair<T>(rangeToSortTarget[0], rangeToSortTarget[1]),
IteratorPair<TIndex>(indicesRange[0], indicesRange [1])
);
}
完整示例:
#include <iostream>
#include <initializer_list>
#include <vector>
#include <utility>
template<typename Iterator>
using IteratorPair = std::pair<Iterator,Iterator>;
template<typename T, typename TIndex>
void sortUsingIndicesToTargetContainerPair
(
const IteratorPair<T>& rangeToSortSource,
const IteratorPair<T>& rangeToSortTarget,
const IteratorPair<TIndex>& indicesRange)
{
}
template<typename T, typename TIndex, std::size_t N>
constexpr void sortUsingIndicesToTargetContainerPair2
(
const T(&rangeToSortSource)[N],
const T(&rangeToSortTarget)[N],
const TIndex(&indicesRange)[N]
)
{
static_assert(2 == N, "must be pair");
sortUsingIndicesToTargetContainerPair
(
IteratorPair<T>(rangeToSortSource[0], rangeToSortSource[1]),
IteratorPair<T>(rangeToSortTarget[0], rangeToSortTarget[1]),
IteratorPair<TIndex>(indicesRange[0], indicesRange [1])
);
}
int main() {
std::vector<int> vecs{0,1,2,3,4,5,6,7,8,9};
std::vector<int> indices{9,8,7,6,5,4,3,2,1,0};
auto copy = vecs;
sortUsingIndicesToTargetContainerPair(std::make_pair(vecs.begin(), vecs.end()),
std::make_pair(copy.begin(), copy.end()),
std::make_pair(indices.begin(), indices.end()));
sortUsingIndicesToTargetContainerPair2({vecs.begin(), vecs.end()},
{copy.begin(), copy.end()},
{indices.begin(), indices.end()});
std::cout << "ok\n";
return 0;
}
如果您已经定义了iteratorPair<Iterator>
,则不需要template<typename> class IteratorPair
。
我还建议按值采用(成对)迭代器。 您是否通过常量引用获取(成对)指针?
template<typename T, typename U>
void sortUsingIndicesToTargetContainerPair(
iteratorPair<T>& rangeToSortSource,
iteratorPair<T>& rangeToSortTarget,
iteratorPair<U>& indicesRange);
你有几个问题:
{..}
没有类型,只能推导出为std::initializer_list<T>
或T(&)[N]
。
模板参数不能将别名推断为别名,
即iteratorPair<SomeType>
(又名std::pair<SomeType, SomeType>
)不会匹配template <typename> class Pair
。
我们在默认模板( std::vector<T, Allocator /*=SomeDefault<T>*/>
for template <typename T> Container
)中遇到了类似的“问题”,该问题已在 C++17 中解决。 我不认为可能有“冲突”/重复的别名的解决方案是可能的。
正如 Caleth 所提到的,您可能无论如何都不想对此进行扣除。
您的iteratorPair
似乎定义了一个范围,但您的常量具有误导性。 const iteratorPair<std::vector<int>::iterator>
允许修改底层容器。 使用真正的范围类型似乎更合适。
为了允许您的调用语法,您可能会摆脱std::pair
并执行以下操作:
// SourceIt might be different than TargetIt (iterator and const_iterator mainly)
template <typename SourceIt, typename TargetIt, typename IndexesIt>
void sortUsingIndicesToTargetContainerPair(
const SourceIt (&rangeToSortSource)[2],
const TargetIt (&rangeToSortTarget)[2],
const IndexesIt (&indicesRange)[2])
{ /*...*/ }
但是,为了保持您对范围的想法,您甚至可以这样做
template <typename Source, typename Target, class Indexes>
void
sortUsingIndicesToTargetContainerPair(
const Source& rangeToSortSource,
Target& rangeToSortTarget,
/*const*/ Indexes& indicesRange)
{ /*...*/}
你甚至有更简单的调用语法:
sortUsingIndicesToTargetContainerPair(vecs, copy, indices);
sortUsingIndicesToTargetContainerPair(my_sub_range(vecs, /*..*/),
my_sub_range(copy, /*..*/),
my_sub_range(indices, /*..*/));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.