我現在正在與以下提案作鬥爭,並且我想知道法律以及在較小程度上反對它的道德論點。RVO/NRVO和公開的未定義拷貝構造函數
我們有什麼:
#include <vector>
class T;
class C
{
public:
C() { }
~C() { /*something non-trivial: say, calls delete for all elements in v*/ }
// a lot of member functions that modify C
// a lot of member functions that don't modify C
private:
C(C const &);
C& operator=(C const&);
private:
std::vector< T* > v;
};
void init(C& c) { } // cannot be moved inside C
// ...
int main()
{
// bad: two-phase initialization exposed to the clients
C c;
init(c);
// bad: here follows a lot of code that only wants read-only access to c
// but c cannot be declared const
}
什麼已經提出:
#include <vector>
class T;
class C
{
public:
C() { }
~C() { /*calls delete for all elements in v*/ }
// MADE PUBLIC
C(C const &); // <-- NOT DEFINED
// a lot of member functions that modify C
// a lot of member functions that don't modify C
private:
C& operator=(C const&);
private:
vector< T* > v;
};
C init() // for whatever reason object CANNOT be allocated in free memory
{
C c;
// init c
return c;
}
// ...
int main()
{
C const & c = init();
}
這編譯並使用最新G ++(這是唯一的目標編譯器)鏈接(和作品)都4.1.2和4.4.5-由於(N)RVO,複製構造函數永遠不會被調用;僅在main()的末尾調用析構函數。
聲稱該技術是完全正確的,因爲沒有辦法複製構造函數可能被誤用(如果它曾經被生成,它將是鏈接器錯誤),並使其公開,防止編譯器抱怨私人的。
對於我來說,使用這樣的技巧看起來確實是錯誤的,我認爲這與C++精神相矛盾,並且看起來更像是破解 - 這個詞的意義不大。
我的感受並不充分,所以我現在在尋找技術。
請不要張貼教科書C++的東西在這裏:
- 我所知道的「三個規律」,並通過12.8/15和神聖的標準的12.2已經閱讀;
- 我既不能使用
vector<shared_ptr<T> >
也不能使用ptr_vector<T>
; - 我無法在可用內存中分配
C
,並通過C*
從init
返回。
謝謝。
我假設移動施工不適合你? – 2011-04-05 14:15:01
@Konrad Rudolph:不幸的是(g ++ 4.1.2是我們應該支持的編譯器之一,因此沒有0x功能)。 – 2011-04-05 14:17:25
「使其公開可以防止愚蠢的編譯器抱怨私人。」 - 不是愚蠢的編譯器。該標準要求拷貝構造函數即使在拷貝被刪除時也是可訪問的,因爲拷貝elision是可選的。因此,如果它被允許是私密的,那麼依賴elision來避免錯誤的程序無論如何都不會嚴格符合,在這種情況下,標準要求被診斷。編譯器正在幫你編寫可移植的代碼,誠然違揹你的願望;-) – 2011-04-05 14:23:09