2011-11-10 42 views
5

我目前正在看一些可以在GCC的新版本上編譯的代碼,但不能在較舊的版本上編譯。在我的情況下,我正在使用std::back_inserterstd::copy從一個數據結構到一個自定義數據結構的一些數據。如果我忘記了這個自定義數據結構中的typedef value_type & const_reference typedef,那麼這將不會在GCC 4.4上編譯。相同的代碼在GCC 4.5上編譯和運行得很好。std :: back_inserter在舊的GCC上需要const_reference。爲什麼?

這兩個編譯器版本之間的區別是什麼,它使得代碼在一個版本上編譯,而不是在另一個版本上編譯。我猜想這與C++ 11的實現有關,而C++ 11在GCC 4.4中完成得不那麼完整。可能是decltype或另一個新的C++ 11關鍵字,我猜想。

也是這段代碼是正確的,如果我使用std::back_inserter而沒有定義const_reference類型?我通常認爲必須實現全套typedef(value_type,reference,const_reference等)才能與STL算法庫兼容?或者我可以放心地假設,如果我的代碼在這種情況下編譯,我不會調用任何危險的東西(例如移動語義,這會破壞我的其他數據結構)。

+0

備案(幫助像我這樣的初學者節省時間):在我加入 'typedef T&reference; typedef const T&const_reference;' 到我的數據結構中,back_inserter的錯誤c2039消失了。 –

回答

6

該標準(1998)說std::back_insert_iterator需要Container::const_reference。在 「24.4.2.1模板類back_insert_iterator」,[lib.back.insert.iterator],它說:

back_insert_iterator<Container>& 
operator=(typename Container::const_reference value); 

2011年的標準只希望Container::value_type

back_insert_iterator<Container>& 
operator=(const typename Container::value_type& value); 
back_insert_iterator<Container>& 
operator=(typename Container::value_type&& value); 

所以,爲了兼容兩種版本的C++標準都定義了value_typeconst_reference_type

在這兩個GCC 4.4.6和4.5.1的operator=的定義是相同的(libstdc++-v3/include/bits/stl_iterator.h):

back_insert_iterator& 
    operator=(typename _Container::const_reference __value) 
    { 
    container->push_back(__value); 
    return *this; 
    } 

和我得到兩種編譯器相同的錯誤,也許你需要仔細檢查如果你使用正確的編譯器版本。

+0

感謝您的澄清。在4.5.2上它沒有const_reference類型,就像我剛剛驗證的那樣。 4.4.4仍然需要它。 – LiKao

+1

@LiKao,在最近的GCC中,C++ 0x庫兼容性默認情況下處於啓用狀態。 GCC4.5.2比GCC4.4稍微*更兼容:),因爲它僅在禁用兼容性時使用'const_reference',而4.4則無條件使用。 – chill

+0

@chill:引用[當前gcc版本的文檔](http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Standards.html#Standards):'默認的,如果沒有C++語言方言選項給出,是-std = gnu ++ 98.'。那麼,你確定你說什麼嗎? –

1

,你需要const_reference爲您的數據結構定義的原因是因爲在GCC 4.4賦值運算符在std::back_insert_iterator類的左值參數類型定義爲:

template<class Container> 
back_insert_iterator<Container>& 
back_insert_iterator<Container>::operator= 
        (typename Container::const_reference value); 

因此const_reference需要是在您的類中輸入可解析標識符以正確實例化std::back_insert_iterator類模板中的賦值運算符。

在GCC 4.5,對於左值參數的賦值運算符的這個定義已改爲

template<class Container> 
back_insert_iterator<Container>& 
back_insert_iterator<Container>::operator= 
       (const typename Container::value_type& value); 

爲了支持新的C++ 11規範。由於您的代碼能夠正確編譯GCC 4.5,因此我假設您必須爲您的數據結構正確定義value_type

相關問題