[英]What does `std::swap` do when applied to these objects?
編碼
using namespace std;
class A
{
private:
vector<int> a;
public:
A(vector<int> x):a(x){}
string toString()
{
string s;
for (auto& element : a)
{
s += to_string(element) + " ";
}
return s;
}
};
int main()
{
A a1({1,2,3});
A a2({11,12,13});
cout << "a1 = " << a1.toString() << "\n";
cout << "a2 = " << a2.toString() << "\n";
swap(a1,a2);
cout << "a1 = " << a1.toString() << "\n";
cout << "a2 = " << a2.toString() << "\n";
return 0;
}
預期的輸出
a1 = 1 2 3
a2 = 11 12 13
a1 = 11 12 13
a2 = 1 2 3
從cplusplus.com> std :: swap在復雜性下
非數組:常量:精確地執行一種構造和兩種分配(盡管請注意,這些操作中的每一種都基於其自身的復雜性)。
數組: N中的線性:每個元素執行交換操作。
這是否意味着將std::swap
應用於a1
和a2
僅交換指向數組[1,2,3]
和[11,12,13]
的指針,而不復制任何int
或其他內容?
將std::swap
應用於類A
兩個對象時究竟能做什么?
假設std::swap
復制了數組的所有元素,我應該使用vector::swap
編寫一個static A::swap
函數,其時間復雜度是恆定的(來自cplusplus.com> vector :: swap ),這意味着它僅交換指針?
[..]要添加注釋,說明
std::swap
的語義在C ++ 17中已更改。 因此,最好提一下編譯器,其版本和目標標准。
我希望一個簡單的問題不會帶來C ++標准和編譯器版本的復雜性。 我通常在C ++ 11中編譯我的代碼。 為了完整起見,這里是筆記本電腦上的gcc版本。
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
要求std::swap
模板的type參數必須為MoveConstructible和MoveAssignable。 這表明swap
可以大致寫成(省略了幾位)
void swap(T &a, T &b) {
T tmp{std::move(a)};
a = std::move(b);
b = std::move(tmp);
}
對於您的示例類,它將多次調用默認的move ctor / move賦值運算符( A
edit:),而它們又將調用std::vector
。 IOW,您可以期望您的程序保持原樣的效率。
另外,您可以在與A
相同的名稱空間中定義一個非成員swap
函數,並使用矢量參數顯式調用std::swap
。 或直接調用std::vector::swap
。
根據您的編譯器和所使用的類/類型,使用swap函數將復制其中一個類,或使用move構造函數/賦值(C ++ 11及更高版本)( http://en.cppreference.com/w / cpp / utility / move )。
您的類僅包含一個向量,對於向量類,此move構造函數可以執行您簡單地稱為“交換指針”的操作,因此非常快。 請注意,實現例如復制構造函數將刪除隱式聲明的move構造函數,從而使這種“魔術”發生! ( http://en.cppreference.com/w/cpp/language/move_constructor#Implicitly-declared_move_constructor )
在獨立查看交換功能時,我給您帶來大量的后續見解:交換功能最著名的用途之一是在復制和交換習慣中( https://progdoo.wordpress.com / 2012/06/03 / c11-copy-and-swap-idiom / )。 這對於已實現的移動構造器/分配最有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.