[英]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::begin
的const
版本的主體中,表達式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.