簡體   English   中英

如何將 std::pair 迭代器傳遞給函數模板並推導出迭代器類型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM