2015-05-28 63 views
4

我可以在C++標準的草案N4431中找不到transform_n函數。爲什麼C++標準庫中沒有std :: transform_n函數?

這是故意的嗎?如果不是的話,那麼人們會如何爲未來版本的標準提出建議?

這是我將如何實現它:

template<typename _InputIterator, typename Size, typename _OutputIterator, typename _UnaryOperation> 
_OutputIterator transform_n(_InputIterator __first, Size __n, _OutputIterator __result, _UnaryOperation __op) { 
    for(Size i=0;i<__n;++i) 
     *__result++ = __op(*__first++); 
    return __result; 
} 


template<typename _InputIterator1, typename Size, typename _InputIterator2, typename _OutputIterator, typename _BinaryOperation> 
_OutputIterator transform_n(_InputIterator1 __first1, Size __n, _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) { 
    for(Size i=0;i<__n;++i) 
     *__result++ = __binary_op(*__first1++, *__first2++); 
    return __result; 
} 
+0

請參閱https://isocpp.org/std/submit-a-proposal。一定要拿出一些引人注目的用例。 – chris

+0

@TonyD:這不僅僅是因爲你不能通過兩次相同的輸入迭代器,所以它可以節省你的時間。但是你可以使用帶有lambda的'std :: generate_n'。 – rici

+5

我會更感興趣的是在迭代器(或範圍)本身編碼,而不是每個算法都有一個'_n'版本。例如,Eric Niebler的[範圍庫](https://github.com/ericniebler/range-v3),它具有'take(N)'適配器,它採用範圍的前N個元素。 –

回答

2

這裏的另一種可能的實現,這表明已經有一個庫函數具有等效功能:

template<typename _InputIterator, 
     typename _OutputIterator, 
     typename _UnaryOperation> 
_OutputIterator transform_n(_InputIterator __first, 
          size_t __n, 
          _OutputIterator __result, 
          _UnaryOperation __op) { 
     return std::generate_n(__result, __n, 
          [&__first, &__op]() -> decltype(auto) { 
           return __op(*__first++); 
          }); 
} 

由於@TonyD在提到註釋,這有強制轉換按順序發生的效果,但如果輸入迭代器參數實際上只是一個輸入迭代器,則情況已經如此。

編輯:根據@ T.C。的建議,我將lambda改爲返回類型爲decltype(auto),如果我理解正確,它可以允許通過輸出迭代器移動語義。這需要最近的編譯器,因爲它是一個C++ 14功能。

+1

lambda應該返回'decltype(auto)'。 –

+0

@ T.C:好的。我也做了它(正確的,我認爲)通過generate_n的返回值。 – rici

+1

'decltype(auto)'的意思是讓lambda返回到'__op'返回的內容。如果調用返回某個東西的引用,則不想複製 - 表示某些內容甚至可能不可複製! C++ 11相當於' - > decltype(/ *表達式返回* /)'。 TBH,獲得正確的lambda是非常棘手的,我可以看到一個圖書館解決方案的爭論。 –

相關問題