[英]Why are std::allocator::construct and std::allocator::destroy templated on element type?
[英]Is it wrong if the standard container element type and std::allocator type are different?
從這里開始 (這是相當古老的):
用於allocator模板參數的類型和用作標准容器中的元素類型的類型一致也很重要。 例如:
std::list<int, std::allocator<long> > // Wrong!
不行。
題
以上陳述是否正確(或者是否正確)? 無論我在std::allocator
為T
做什么,我所做的任何測試似乎都能正常工作。 例如, std::vector<int, std::allocator<std::string>>
編譯並正常工作推回和擦除元素等(根據我的理解std::allocator<std::string>::rebind<int>::other
是使這項工作變得神奇的魔力。
我在這里添加一個答案,以澄清不良行為和未定義行為之間的區別。
[intro.compliance] / P1:
可診斷規則集包含本國際標准中的所有語法規則和語義規則,但那些包含“無需診斷”的明確表示法或被描述為導致“未定義行為”的規則除外。
[defns.ill.formed]:
程序不完善
[defns.well.formed]
C ++程序根據語法規則,可診斷語義規則和單定義規則(3.2)構建。
在英語中:不正確的程序應具有與之相關的診斷。 未定義的行為可以做任何事情:
(除了第4次以外通常都會在實踐中發生)
未定義的行為非常糟糕,而imho,C和C ++標准過於寬松地應用了該規范。
從技術上講,違反Requires子句會導致未定義的行為。
[res.on.required] / P1:
違反函數的Requires:段中指定的前提條件會導致未定義的行為,除非函數的Throws:paragraph指定在違反前提條件時拋出異常。
如MSN所述, allocator_type::value_type
應與表99中所述的container::value_type
相同 - 可識別分配器的容器要求 。
allocator_type A Requires: allocator_type::value_type
is the same as X::value_type.
( X
表示一個分配器感知容器類,其value_type
為T
使用類型A
分配器)
所以違反如下:
std::list<int, std::allocator<long> >
是未定義的行為。 所以:
就在最近(在我寫這篇文章的幾周內),libc ++( http://libcxx.llvm.org )已經開始用static_assert
診斷這個未定義的行為,以便你盡快得到壞消息。
我們決定采用這個方向,而不是允許行為,因為容器沒有設置為允許密切相關類型之間的轉換。 例如:
std::list<int, std::allocator<long>> list1;
std::list<int> list2 = list1; // is specified to not work
即如果你開始將list1
和list2
視為等效類型,因為std::allocator
無論如何都會rebind
,當你發現這兩個列表實際上是不同的類型並且無論如何都不能進行互操作時,你會感到很失望。 所以最好盡快得到壞消息,而不是在2個月或2年之后發現,當你嘗試將它們用作等效類型時。
也許未來的標准會將list1
和list2
視為等效類型。 它在技術上大多數可能( std::is_same
可能不起作用)。 但是我沒有聽到過這方面的建議。 這個方向對我來說似乎不太可能。 使用static_assert
,錯誤很容易被診斷出來。 相反,我希望看到標准的方向是使這個代碼形成錯誤而不是未定義。 這樣做最困難的部分是字標准,而不是std :: lib實現。
編輯:在[containers.requirements.general]中,Allocator感知容器要求表明allocator_type::value_type
與Container::value_type
相同。
因此,傳入具有不同value_type
的allocator類型是value_type
,盡管至少有一個實現只使用allocator_traits<...>::rebind<value_type>
來獲取正確的分配器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.