2012-10-07 60 views
1

看來,要測試常量,必須測試模板參數,但要測試右值,必須測試實際參數。 (這是使用VC++ 2012.)這段代碼說明了我的意思:澄清通緝。 C++ type_traits

#include <type_traits> 
#include <string> 
#include <iostream> 

using namespace std; 

template<class T> 
void f(T& x) { 
    cout << "f() is_const<T> and is_const<decltype<x)>" << endl; 
    cout << is_const<T>::value << endl; // Prints 1 when arg is const 
    cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is const 
} 

template<class T> 
void g(T&& x) { 
    cout << "g() is_const<T> and is_const<decltype<x)>" << endl; 
    cout << is_const<T>::value << endl; // Prints 0 when arg is const 
    cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is cons 
    cout << "g() is_rvalue_reference<T> and is_rvalue_reverence<decltype(x)>" <<endl; 
    cout << is_rvalue_reference<T>::value << endl; // Prints 0 when arg is rvlaue 
    cout << is_rvalue_reference<decltype(x)>::value << endl; // Prints 1 when arg is rvalue 
} 

int main() 
{ 
    const std::string str; 
    f(str); // const argument 
    cout << endl; 
    g(std::string("")); // rvalue argument 
    return 0; 
} 

我很努力地理解這是爲什麼。有人可以解釋,或者指給我一篇解釋它的文章嗎?如果需要,我將深入研究C++ 11標準。任何人都知道有關的部分?

+2

'const'是*型*的一部分。 「Rvalue」是一個值類別,它是*表達式*的一部分。兩件不同的事情。 –

回答

5

原因是你誤解了事情。 x在任何這些示例中都不會是const,只是因爲沒有const引用類型(無論如何您都無法更改引用)。在is_const<T>你基本上忽略了你宣稱xT&

一個類似的誤解正在爲rvalue ref測試工作。 T&&(稱爲通用參考,btw)將在通過左值時推導爲U&,當您傳遞右值時推導爲U。在測試is_rvalue_reference<T>時,您再次忽略了您宣稱xT&&。在測試is_const<T>時,您沒有考慮到T將作爲參考,如上所述,該參數永遠不可能爲const

g正確的測試將是

  • std::is_const<typename std::remove_reference<T>::type>::value
  • std::is_rvalue_reference<T&&>::value
+0

謝謝。我不好意思不好意思,或者這個問題可能已經做到了。我猜想,讓我困惑的一件事是,is_const ::值從不是真實的參考,儘管所有參考的性質是不變的。這是指針和參考之間的主要區別。 Const指針必須這樣聲明。我試着聲明一個引用爲const。 VC++ 2012告訴我這是一個「時代錯誤」。在VC++ 2012頭文件中,有一個is_const 來自false_type的專門化。所以一個參考is_const永遠不會,儘管它始終是不變的。 –

+0

@Jive:讓你聽起來像你認爲標準是有道理的。 :) – Xeo

+0

我在80年代後期就放棄了。我甚至質疑添加參考文獻的智慧。 const指針有什麼問題?當然,這是在模板之前。用指針,語法清楚地表明你正在處理一個參考(按照常識來說)。與「參考」不同。「順便說一句,我認爲VC++使用了與「不合時代」不同的詞。 「過時的」我認爲是。 –