2013-10-01 57 views
1

當模板參數T是基本類型(如int(在gcc 4.8上))時,以下代碼無法編譯。這是標準符合行爲嗎?我對std::declval的理解是,它總是解析爲T&&T&在基本類型上使用std :: declval

template <class T> 
void foo(T&& val) 
{ 
    std::cout << noexcept(std::declval<typename std::decay<T>::type>() = val); 
} 

struct bar { }; 
bar b; 
foo(b); // okay 

int a; 
foo(a); // error: using xvalue (rvalue reference) as lvalue 

錯誤發生在分配valstd::declval表達的點。

它工作,如果我刪除std::decay和直接使用std::declval<T>,但我不知道爲什麼。腐朽型應該只是int,所以std::declval<int>()應該有一個返回類型int&&不應該嗎?

+0

看來你試圖複製'std :: is_nothrow_copy_assignable'函數? – kennytm

+0

差不多。如果'T'是一個左值引用,我想檢查是否有複製賦值,但是如果'T'是一個右值引用,我想檢查是否移動賦值。 – marack

回答

3

你正在嘗試賦值給右值。 std::declval<int>()正確返回一個類型int&&。它沒有名稱,所以它是一個類型爲int的右值(更確切地說是xvalue)。然後你試圖將val賦值給這個右值,這對於基本類型是非法的。

這裏有一個live example以簡化形式展示問題(沒有declval)。

+0

+1在foo裏面,val的類型是int&,沒有衰減,declval也給你int&。隨着衰變,你得到int& - > int - > int &&。 – jrok

+0

啊,當然。我應該使用'std :: declval :: type>()'來代替。謝謝! – marack

+1

@marack或者只是'std :: declval ()':P – Simple