2011-08-21 102 views

回答

10

在閱讀完本教程後,我對自己的措辭有些困惑。但我相信它是如此簡單:該教程是解釋爲什麼allocator的模板標題顯示

allocator(const allocator&) throw();

template <class U> allocator(const allocator<U>&) throw();

即使拷貝構造函數是一個allocator相當無用的。答案是分配器的規範不允許構造函數拋出異常。因此,複製構造函數public接口定義了複製構造函數,其異常規範爲throw()(不會拋出任何異常),以防止某個人使用可能拋出異常的複製構造函數派生自己的分配器。

請參閱this link瞭解異常規範是什麼,如果這就是拋出你的東西。 (沒有雙關語意思。)

所以,他們並不是說在創建分配器時,你必須提供一個拷貝構造函數。他們只是指出該規範明確禁止你定義拋出任何異常的規範。 `

1

分配器需要一個拷貝構造函數,因爲容器有一個拷貝構造函數,並且需要在進程中拷貝它們的分配器。

+1

在C++ 11之前,分配器必然是無狀態的。因此調用默認構造函數就足夠了。Post C++ 11,分配器是否在特定情況下被其封裝容器複製,取決於分配器的存在和定義'select_on_container_X_Y'方法。請參閱[分配器特徵參考](http://en.cppreference.com/w/cpp/memory/allocator_traits) – apmccartney

4

您必須顯式編寫一個拷貝構造函數(而不是使用缺省值),因爲需要使用異常說明符throw()來定義C++ 03分配器的拷貝構造函數。默認的拷貝構造函數沒有這個說明符。

從技術上講,你不要,但如果它確實會拋出一個異常......好吧,祝你好運。

但這只是一個小小的煩惱,因爲C++ 03中的分配器不能有狀態。所以你不應該複製周圍的成員。複製構造函數可以是空的。

+1

Nicol Bolas,如果allocator(const allocator&)= delete;它會好嗎?就像我們在2016年一樣 –

0

其實很簡單。使用分配器的容器的構造函數使用分配器並存儲它的副本。爲此,它需要分配器爲CopyConstructible。就這樣。請注意,CopyAssignable不需要的分配器類型,除非其propagate_on_container_copy_assignment特性爲真(這很罕見)。

C++ 11規範還聲明「對這些類型沒有構造函數,比較運算符,複製操作,移動操作或交換操作應通過異常退出」。異常規則允許你創建一個分配器的(堆棧)副本(特別是在構建或銷燬時),而不用擔心複製分配器會拋出。幾乎不可能設計容器,這些容器在存在可能導致複製,移動,交換或比較的分配器的情況下是異常安全的。在實踐中,分配器不能比指向某個資源的指針多,因此允許分配器拋出副本等,會增加很多痛苦,幾乎沒有收益。