![](/img/trans.png)
[英]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.