簡體   English   中英

尾隨返回類型,decltype和const-ness

[英]Trailing return types, decltype and const-ness

我正在試驗新的尾隨返回類型,我遇到了這個(簡化的)代碼的問題

#include <list>

class MyContainer{
  std::list<int> ints;

  auto begin( ) -> decltype(ints.begin())
  {
    return ints.begin();
  }

  auto begin( ) const -> decltype(ints.begin())
  {
    return ints.begin();
  }
};

忽略這段代碼毫無意義的事實。 重要的部分是使用GCC 4.6.1時生成的編譯器錯誤(使用-std=c++0x標志):

In member function 'std::list<int>::iterator MyContainer::begin() const':
error: could not convert '((const MyContainer*)this)->MyContainer::ints.std::list<_Tp, _Alloc>::begin [with _Tp = int, _Alloc = std::allocator<int>, std::list<_Tp, _Alloc>::const_iterator = std::_List_const_iterator<int>]()' from 'std::list<int>::const_iterator {aka std::_List_const_iterator<int>}' to 'std::list<int>::iterator {aka std::_List_iterator<int>}'

如果您不喜歡涉及模板的錯誤,那么簡短的故事就是在MyContainer::beginconst版本的主體中,表達式ints.begin()返回類型為std::list<int>::const_iterator的值。 std::list<int>::const_iterator (因為ints在這樣的上下文中是const )。 但是, decltype(ints.begin())生成類型std::list<int>::iterator ,即decltype在決定表達式的類型時忽略 begin方法的const限定符。 不出所料,結果就是類型沖突。

在我看來這是GCC編譯器中的一個錯誤。 只有使用decltype來表示const限定符並生成const_iterator類型才有意義。 任何人都可以確認或否認(甚至可以解釋)這個嗎? 也許我忽略了decltype ,但這看起來非常簡單。

注意:據我所知,相同的行為不僅適用於std::list<int> ,而且適用於在const -ness上重載成員函數的任何類型,這些類型返回不兼容的類型。

你是對的,這是一個錯誤。 根據N3291,第5.1.1節,第3段:

如果聲明聲明了類X的成員函數或成員函數模板,則表達式是可選的cv-qualifer-seq和函數定義結束之間的類型為“指向cv-quali fi er-seq X的指針”的prvalue。 ,成員聲明者或聲明者。 它不應出現在可選的cv-quali-seq之前,它不應出現在靜態成員函數的聲明中(盡管它的類型和值類別是在靜態成員函數中定義的,因為它們在非靜態成員函數中) 。 [注意:這是因為在完整的聲明符已知之前不會發生聲明匹配。 -end note]與其他上下文中的對象表達式不同,*為了成員函數體之外的類成員訪問(5.2.5),這不需要是完整類型。 [注意:只有在聲明之前聲明的類成員才可見。 - 尾注]

但這是最近一份工作草案與N3291之間的最新變化。 所以GCC在不到6個月前是對的; 這就是將代碼編寫到移動規范中的危險。

暫無
暫無

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

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