請理解,我仍然在學習C++ 11的移動和右值語義的概念。我的問題是遺留代碼是否可以通過簡單地使用C++ 11編譯器和STL免費獲得避免不必要拷貝的午餐。C++ 11右值和移動:遺留代碼是否可避免複製?
這是一個非常簡單的例子。此代碼爲給定的字符串構建一個簡單的字符頻率表。例如,「apple」應返回{('a', 1), ('e', 1), ('l', 1), ('p', 2)}
。你會看到,我只是使用向量作爲值。
typedef std::tuple<char, int> Frequency;
typedef std::vector<Frequency> Frequencies;
Frequencies buildFrequenciesTable(std::string w) {
char table['z' - 'a' + 1] = { 0, };
std::for_each(w.cbegin(), w.cend(), [&table](char c) {
++table[::tolower(c) - 'a'];
});
Frequencies freqs;
for (size_t i = 0; i < 'z' - 'a' + 1; ++i) {
if (table[i] != 0)
freqs.push_back(tuple<char, int>((char) ('a' + i), table[i]));
}
return freqs; // Q1: Is vector get copied?
}
int main() {
using namespace std;
Frequencies f1 = buildFrequenciesTable("apple"); // Q2: Copy?
Frequencies f2 = buildFrequenciesTable("banana");
vector<Frequencies> fs = { f1, f2 }; // Q3: Copy?
}
清楚的是,C++ 03返回向量作爲值時生成所有拷貝代碼(使用拷貝構造函數和賦值運算符)。在C++ 11中怎麼樣? std::vector
a有移動構造函數。這段代碼能避免任何unnessarry副本嗎?或者,我應該在上面的代碼中使用&&
還是std::forward
?
我試圖調試內部的STL代碼,但很難說服。
注:我的目標是最大限度地減少這些功能中不必要的副本。我知道我可以使用新的/指針/引用,但這將需要解決內存泄漏問題。所以,我想盡可能地使用價值。
謝謝!那麼,基本上,在Q1和Q2的情況下,C++ 11的r值引用和移動語義沒有什麼好處?我的理解正確嗎? – Nullptr
我的目標實際上是儘量減少這些功能中不必要的副本。我知道我可以使用新的/指針/引用,但這將需要瘋狂的泄漏問題。所以,我想盡可能地使用價值。 – Nullptr
還有一個子問題(可能是個愚蠢的問題):我可以做更多的優化代碼嗎?例如,在'buildFrequenciesTable'中返回'Frequencies &&',或者聲明'Frequencies && f1'左右。特別是,上面的'f1'和'f2'不會被修改。 – Nullptr