2014-02-10 22 views
3

的向量我已經編譯好上的Microsoft Visual C++一個非常簡單的演示程序:GNU C++不能創建常量自定義類實例

#include <cstdio> 
#include <vector> 
#include <string> 

using namespace std; 

class String 
    :public wstring 
{ 
public: 
    String(void) 
    { 
    } 

    String(const String &other) 
     : wstring(other) 
    { 
    } 
}; 

int main(void) 
{ 
    vector<const String> v; 
    v.push_back(String()); 
    printf("Hello, World!"); 
    return 0; 
} 

它創建的字符串常量的載體。但是,在GNU C++ 4.8.2中,它提供了很多錯誤,試圖說無法創建常量String對象的向量。當我用vector<String>代替vector<const String>時,它編譯。 這種GNU C++行爲的原因是什麼?

+2

對於某些操作,類型必須是可賦值的(和/或移動變體)。 'const T'不能滿足這個要求。 – juanchopanza

回答

4

標準庫容器使用分配器的。對於一個allocator感知容器類型X及其分配AX::value_typeA::value_type必須相同。由於您的X::value_typeconst StringA::value_type也將const String。然而,該標準只定義與分配器value_type s表示它是「任何非const,非參考對象類型」(表27 [allocator.requirements])沒有定義用於與const類型的分配器的要求,所以只是試圖創建具有const值類型的容器將導致未定義的行爲。

除此之外,在集裝箱上的許多操作需要的價值類型爲複製/移動分配的,所以你可能不會使用它走得很遠。

+0

未定義的行爲? OP說它是編譯時錯誤。 –

+2

@KarolyHorvath對於有未定義行爲的代碼來說錯誤是完全有效的。 –

+0

謝謝,你一定是對的; GNU無法編譯代碼並且MSVC編譯的事實表明它確實是「未定義」的行爲,所以微軟決定允許它編譯,而GNU不允許。 – Vitaliy

5

std::vector涉及在關於內存管理的一種特定的方式你的類的實例。它對數據執行的一些操作需要拷貝構造函數和賦值運算符,或者使用noexcept移動構造函數/賦值運算符。海灣合作委員會是不正確的編譯你的例子,沒有任何這些。 const T不能是std::vector的有效類型。