簡體   English   中英

為什么C ++ 11從std :: vector的fill構造函數原型中刪除默認值?

[英]Why did C++11 remove the default value from the prototypes of std::vector's fill constructor?

在C ++ 98中, std::vector的fill構造函數的原型具有初始化程序的默認值。

explicit vector (size_type n, const value_type& val = value_type(),
                 const allocator_type& alloc = allocator_type());

C ++ 11使用兩個原型。

explicit vector (size_type n);
         vector (size_type n, const value_type& val,
                 const allocator_type& alloc = allocator_type());

(在C ++ 14中,填充構造函數再次更改,但這不是這個問題的重點。)

參考鏈接在這里

為什么C ++ 11不贊成使用默認的初始化值value_type()

順便說一句,我嘗試使用clang++ -std=c++11編譯以下代碼,並發出錯誤,這意味着值類型仍需要具有默認構造函數,例如S() {} ,即是默認可構造的。

#include <vector>

struct S {
    int k;
    S(int k) : k(k) {} // intentionally remove the synthesized default constructor
};

int main() {
    std::vector<S> s(5); // error: no matching constructor
}

C ++ 98提取了一個原型對象,然后將其復制了n次。 默認情況下,原型是默認構造的對象。

C ++ 11版本構造了n個默認構造的對象。

這消除了n個副本,並用n個默認構造替換了它。 另外,它避免了構建原型。

假設您的課程如下所示:

struct bulky {
  std::vector<int> v;
  bulky():v(1000) {} // 1000 ints
  bulky(bulky const&)=default;
  bulky& operator=(bulky const&)=default;

  // in C++11, avoid ever having an empty vector to maintain
  // invariants:
  bulky(bulky&& o):bulky() {
    std::swap(v, o.v);
  }
  bulky& operator=(bulky&& o) {
    std::swap(v,o.v);
    return *this;
  }
};

這是一個始終擁有1000 int的緩沖區的類。

如果然后創建一個bulky的向量:

std::vector<bulky> v(2);

在C ++ 98中,這分配了3次1000整數。 在C ++ 11中,它僅分配2乘以1000整數。

另外,C ++ 98版本要求該類型是可復制的。 C ++ 11中有不可復制的類型,例如std::unique_ptr<T> ,並且不能使用C ++ 98簽名生成默認構造的唯一指針vector C ++ 11簽名沒有問題。

std::vector<std::unique_ptr<int>> v(100);

如果我們仍然具有C ++ 98版本,則上述方法將無效。

構造函數一分為二的原因是為了支持“僅移動”類型,例如unique_ptr<T>

此構造函數:

vector(size_type n, const T& value, const Allocator& = Allocator());

要求T是可復制構造的,因為必須從value復制n T s才能填充vector

此構造函數:

explicit vector(size_type n, const Allocator& = Allocator());

不需要 T是可復制構造,只有缺省構造。

后一個構造函數與unique_ptr<T>

std::vector<std::unique_ptr<int>> s(5);

而前一個構造函數則沒有。

這是進行此更改的提案: http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1858.html#23.2.4.1%20-%20vector%20constructors,%20copy ,%20和%20分配

而且,盡管具有一些基本原理,但本文還是有一些基本依據: http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html

Fwiw, resize

void resize(size_type sz, T c = T());

分為:

void resize(size_type sz);
void resize(size_type sz, const T& c);

出於完全相同的原因。 第一個需要默認可構造但不可復制構造(以支持默認可構造僅移動類型),第二個需要可復制構造。

這些更改並非100%向后兼容。 對於某些類型(例如,引用計數的智能指針),默認構造對象的副本構造與默認構造不同。 但是,支持僅移動類型的好處被認為值得此API損壞的代價。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM