2011-01-06 90 views
2

是否有任何常見的方法來擺脫自定義的「分配」仿函數?的std ::變換可能是巨大的,但根據C++標準它禁止源元件修改集合的每個元素

的目標是使用如多聲明方法儘可能

template <typename T> 
struct assign : std::binary_function<T, T, void> { 
    void operator()(const T& source, T& dest) { 
     dest = source; 
    } 
}; 

int main() { 
    static boost::array<int, 5> arr = { 1, 2, 3, 4, 5 }; 
    std::for_each(arr.begin(), arr.end(), 
     boost::bind(assign<int>(), boost::bind(std::plus<int>(), _1, 3), _1)); 
    return 0; 
} 
+0

好問題。修改每個元素將允許將文本字符串就地轉換爲全部小寫或全部大寫。 – 2011-01-06 00:10:41

回答

3

STD修改集合元素::變換的變形例()確實允許輸出迭代器指向與輸入範圍的開始相同的元素。見here。代碼示例顯示了這一點,它演示了具有兩個輸入範圍的轉換。輸出迭代器與第一個輸入迭代器相同。這是否使它更可口?

+1

是的,這個工程。但是標準說(參見25.3.4變換):... op和binary_op不應該使迭代器或子範圍無效,或者修改範圍[first1,last1] ... – Voivoid 2011-01-06 00:17:27

+0

中的元素。這不會修改元素,它會替換他們。這不會使迭代器無效。 – OrangeDog 2011-01-06 00:21:08

+0

它修改了迭代器指向的地方,沒有迭代器本身。新值仍將由同一個迭代器指向。 – 2011-01-06 00:25:02

2

嘗試Boost.Lambda:

int main() { 
    using namespace boost::lambda; 
    static boost::array<int, 5> arr = { 1, 2, 3, 4, 5 }; 
    std::for_each(arr.begin(), arr.end(), _1 += 3); 
    return 0; 
} 

然而,那只是一個 「for_each的」 循環:

int main() { 
    static boost::array<int, 5> arr = { 1, 2, 3, 4, 5 }; 
    BOOST_FOREACH(int& n, arr) { 
     n += 3; 
    } 
    return 0; 
} 
+0

謝謝。boost :: lambda看起來不錯。 BOOST_FOREACH也很棒,但它不允許用這對迭代器指定所需的序列。我仍然想知道std :: transform是否可以用來修改輸入序列。任何意見將不勝感激 – Voivoid 2011-01-06 00:42:13

1

什麼@gregg說加:

標準的措辭( N1905 25.2.3第2段)禁止變換函數直接修改給定範圍內的元素,即不能寫入輸入迭代器。它只應該計算一個值,transform函數然後將其分配給result迭代器。實際上,第5款明確允許result等於first

我想這可能會允許實現在特定情況下執行安全檢查或優化。

例如,假設transform專門針對std::vector<char>。在32位機器上,實現可以將主循環展開4次,並執行32位加載並存儲而不是8位。顯然,如果首次調用轉換函數修改了輸入範圍(其餘3個調用在存儲操作髒數據之前),則這不起作用。

這裏是C++ 03的一行添加3〜每個值關arr

std::transform(arr.begin(), arr.end(), arr.begin(), std::bind1st(std::plus<int>(), 3));

相關問題