![](/img/trans.png)
[英]While doing copy-elision, the compiler doesn't consider the copy constructor in overload resolution, when the move constructor is deleted. Why?
[英]How to enforce copy elision, why it won't work with deleted copy constructor?
我上課不好。 復制此文件將有問題。 我想保證它永遠不會被復制,所以我將其復制構造函數deleted
:
class A {
public:
A();
A(const A&) = delete;
};
A fun() {
return A();
};
int main() {
A a = fun();
};
不幸的是,g ++不會基於以下原因進行編譯:
t.cc: In function ‘A fun()’:
t.cc:8:12: error: use of deleted function ‘A::A(const A&)’
return A();
^
t.cc:4:5: note: declared here
A(const A&) = delete;
^
t.cc: In function ‘int main()’:
t.cc:12:13: error: use of deleted function ‘A::A(const A&)’
A a = fun();
^
t.cc:4:5: note: declared here
A(const A&) = delete;
^
但這是一個非常明顯的情況,應使用復制省略,因此不應調用復制構造函數。 為什么會這樣呢?
直到C ++ 17復制省略是一種優化,編譯器才不需要執行,因此類必須是可復制的,因為編譯器可能要復制(即使實際上不是)。 在C ++ 17中,在許多情況下都可以保證復制省略,然后類將不需要復制ctor。
也可以看看:
http://en.cppreference.com/w/cpp/language/copy_elision
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html
https://herbsutter.com/2016/06/30/trip-report-summer-iso-c-standards-meeting-oulu/ (有關“保證復制省略”的內容)
您也許可以使用在類中聲明復制構造函數的舊技巧,但實際上並未實現它? 只要編譯器實際上不調用復制ctor,就應該滿意。 我沒有對此進行測試,但是我相信它應該在C ++ 17到來之前適用於您的情況。
您無法強制進行復制省略(請參閱其他答案)。
但是,您可以為您的類提供默認的move構造函數,如果無法使用RVO / NRVO,它將移動(因此,不復制)返回值。 為此,您應該為您的move構造函數添加= default
:
class A {
public:
A() = default;
A(const A&) = delete;
A(A&&) = default;
A& operator=(A&&) = default;
};
返回值優化(RVO和NRVO)並不意味着必須放棄可復制或可移動類型所涉及的類型。 無論是否獲得RVO,此要求均適用。
造成這種情況的最可能原因是沒有(當前)強制執行復制刪除。 這是可能發生的優化,並且基於是否在特定實現中應用了該優化,對代碼進行編譯或編譯都沒有意義。
在C ++ 17中,在某些情況下將強制執行RVO,並且將降低可復制性和可移動性的要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.