2014-02-23 39 views
15

給定類型A,B,我關心的是std::common_type<A,B>的確切定義,忽略任意類型A...的可變參數std::common_type<A...>。因此,讓應該std :: common_type使用std :: decay?

using T = decltype(true ? std::declval<A>() : std::declval<B>()); 
using C = std::common_type<A,B>; 

現在,據一些來源,我發現下面的關係(爲簡便起見跳過typename):

  • cppreference.comC::type = std::decay<T>::type

  • cplusplus.comC::type = T

  • GCC 4.8.1 <type_traits> implementationatio N:C::type = std::decay<T>::type如果T是有效的,否則C不包含::type成員( 「SFINAE友好」)

  • 鏘3.3 <type_traits>實現:C::type = std::remove_reference<T>::type

我找到 「SFINAE友好」 版本的海灣合作委員會的一個小細節,而std::remove_referencestd::decay實際上只有不同的內置陣列和功能,再加上cv資格,對此我不再關心。所以我的問題是

它應該是decay<T>::type或只是T?使用decay<T>::type的基本原理是什麼?是否只是代表結果A() + B()爲算術表達式?

例如,嘗試了一下,我發現,在「公正T」的定義的情況下,我們有

common_type<int&,int&> = int& 
common_type<int&,long&> = long 

就是左值參考保持如果類型相同 。這反映了一個事實,即

int a, b; 
(true ? a : b) = 0; 

是有效的,而

int a; 
long b; 
(true ? a : b) = 0; 

不是。 「允許賦值如果類型相同」這種語義正是我在一個應用程序中需要的,我傾向於認爲common_typedecay應該是兩個獨立的步驟。我應該只使用我自己的定義嗎?

+0

'remove_reference'和'decay'也不同在CV-資格引用類型; 'std :: declval '返回一個右值引用。 – dyp

+0

'T'舊(C++ 11),'decay '是新的(C++ 1y),可能存在與此相關的缺陷。讓我看看.. – dyp

+0

@dyp是的,我並不那麼小心,這就是爲什麼我寫了「幾乎」,我會修復。 – iavr

回答

12

應該std :: common_type使用std :: decay?

是的,請參閱Library Working Group Defect #2141

短版(以上長版本,請參見鏈接):

  • declval<A>()返回A&&

  • common_type經由declval指定,n3337:

    template <class T, class U> 
    struct common_type<T, U> { 
        typedef decltype(true ? declval<T>() : declval<U>()) type; 
    }; 
    
  • common_type<int, int>::type因此產率int&&,其中被意外

  • 提出的解決方法是添加decay

    template <class T, class U> 
    struct common_type<T, U> { 
        typedef decay_t < decltype(true ? declval<T>() : declval<U>()) > type; 
    }; 
    
  • common_type<int, int>::type現在產生int

+1

嗯...這實際上表明我們最終如何使用'decay',所以它回答了這個問題,非常感謝。太糟糕了,但我現在必須使用我自己的定義...是的,''應該給int而不是'int &&,但''應該爲'int&'給我。所以只有'declval'添加的'&&'應該被刪除。 – iavr

+0

@iavr LWG頁面的討論包含*「common_type的用戶不期望獲得引用類型作爲結果」*不確定是誰*用戶*。 – dyp

+0

嗯,不是我肯定:-) – iavr

相關問題