2012-08-17 50 views
14

我有一個像下面這樣的類。具有std :: atomic成員變量的類的複製構造函數/賦值運算符的錯誤

#include <atomic> 

static const long myValue = 0; 

class Sequence 
{ 

public: 

    Sequence(long initial_value = myValue) : value_(initial_value) {} 


private: 

    std::atomic<long> value_; 
}; 

int main() 
{ 
     Sequence firstSequence; 
     Sequence secondSequence = firstSequence; 
     return 0; 
} 

我越來越喜歡這個編譯錯誤,

test.cpp:21:36: error: use of deleted function ‘Sequence::Sequence(const Sequence&)’ 
test.cpp:5:7: error: ‘Sequence::Sequence(const Sequence&)’ is implicitly deleted because the default definition would be ill-formed: 
test.cpp:5:7: error: use of deleted function ‘std::atomic<long int>::atomic(const std::atomic<long int>&)’ 

是默認的拷貝構造函數和賦值opertaor不要在這種情況下工作嗎?

PS:我使用的gcc版本4.6.3

回答

14

不能使用標準拷貝構造函數複製原子,因爲所有加載和存儲都必須顯式地進行。你必須編寫你自己的Sequence的拷貝構造函數,它可以做value_(rhs.value_.load())的一些初始化(可能需要更輕鬆的內存排序)。

+0

你能編輯和添加一個編譯代碼的例子嗎?我沒有解決這個問題,我試過了: '序列&operator =(const序列&其他){value_ = other.value_.load();返回*這個; }' – 2017-09-28 20:50:14

+0

@VictorLamoine:不知道你做了什麼,但一般的做法[作品](https://wandbox.org/permlink/ZsHPDqhrIiybq7qf)。 – 2017-09-28 21:35:18

+1

有關如何實際編寫複製構造函數(使用默認的'seq_cst'來加載源代碼,但是避免將原子庫存儲到正在構建的對象中的代價)的詳細信息,請參閱[使用原子成員的類的複製構造函數](https://stackoverflow.com/questions/19961043/copy-constructor-for-classes-with-atomic-member/46045691#46045691)。確保這真的是你想要實現的;複製原子通常與共享狀態的目的相反。 – 2017-10-13 01:34:14

5

因爲沒有std::atomic<long int>::atomic(const std::atomic<long int>&)功能,也沒有辦法讓編譯器創建的Sequence類默認的拷貝構造函數。如果你需要這個類的複製構造函數(如果你想Sequence secondSequence = firstSequence;工作,你會這樣做),那麼你需要編寫一個。由標準所要求

此現象:

原子積分和地址類型列在下面。這些類型應具有標準佈局。它們應該有一個簡單的默認構造函數,constexpr顯式值構造函數,刪除拷貝構造函數,刪除的拷貝賦值操作符以及簡單的析構函數。這些類型應支持聚合初始化語法。

6

Atomic刪除了copy-ctor。所以在你的課堂中複製/移動ctors被刪除。

n3337 12.8/11

隱式聲明的複製/移動構造函數是其類的內聯公共成員。爲刪除的一類X A拖欠複製/移動 構造被定義(8.4.3)如果X具有:

- 類類型M(或其陣列),其不能被複制的非靜態數據成員/移動,因爲 重載解析(13.3),適用於M的對應的構造,導致歧義或 功能是刪除或從默認的構造函數無法訪問,

0

我猜想,選擇刪除標準中的複製構造函數有兩個原因:

  • 通常需要加載/存儲對。有沒有什麼辦法可以強制這一點,當你不控制std :: atomic的調用者時呢?如果std :: atomic <>類型,你正在使用的是is_lock_free()爲false(即在該實現中需要一個互斥量爲整數類型)的類型?你使用什麼複製語義來進行互斥鎖初始化?最終隱式複製的互斥體需要重新初始化,因爲它可能在鎖定狀態下被不幸地複製。我猜std :: mutex也有一個刪除的拷貝構造函數,因此,這也將需求推入std :: atomic。

相關問題