2017-09-03 103 views
3

什麼不合格捕獲lambda被傳遞給apply方法std::valarray? 考慮下面的代碼:爲什麼捕獲lambda不能應用於std :: valarray?

int main() 
{ 
    std::valarray<int> arr = {1, 2, 3, 4, 5, 6}; 
    auto arr1 = arr.apply([](int val) { return val * 2; }); // compiles 
    int n = 3; 
    auto arr2 = arr.apply([n](int val) { return val * n; }); //does not compile 
    return 0; 
} 

住在coliru http://coliru.stacked-crooked.com/a/f0407046699574fc

測試在https://gcc.godbolt.org/
無論是GCC也不MSVC或鐺將編譯上面的代碼

回答

3

的原因是在std::valarray::apply定義:

valarray<T> apply(T func(T)) const; 
valarray<T> apply(T func(const T&)) const; 

的類型兩個成員中的是函數類型。當用作另一個函數的參數類型時衰減到一個函數指針。這些成員函數不接受普通函子。只有指向常規功能的指針。

現在,無捕獲lambda具有隱式轉換運算符到函數指針。所以第一個lambda轉換爲int(*)(int)這是一個可以執行lambda身體的常規函數​​的地址。

但是捕獲狀態的lambda無法以這種方式轉換,並且您可以看到,無法將其作爲參數傳遞給std::valarray::apply

+0

任何想法爲什麼它是在第一個地方完成?也許是因爲它會使向量化或並行化優化不適用於這種「應用」實現? – kreuzerkrieg

+0

@kreuzerkrieg - 'std :: valarray'早在我們引入一種語言的lambda之前就已經構思出來了。另外,我想這會鼓勵傳遞「純粹」功能。我知道,在現代C++中,這是突出的。 – StoryTeller

+0

ummm ...他們爲valarrays添加了std :: begin/end C++ 11的特化功能,爲什麼不添加其他的現代功能...嗯,我想簡單地說valarray並沒有像其他的那樣廣泛使用STL容器。 – kreuzerkrieg

相關問題