2010-09-27 60 views
15

我聽說臨時對象只能分配給常量引用。在C++中使用typedef和模板進行常量引用

但這個代碼提供錯誤

#include <iostream.h>  
template<class t> 
t const& check(){ 
    return t(); //return a temporary object 
}  
int main(int argc, char** argv){ 

const int &resCheck = check<int>(); /* fine */ 
typedef int& ref; 
const ref error = check<int>();/*error */ 
return 0; 
} 

錯誤是得到的是invalid initialization of reference of type 'int&' from expression of type 'const int'

回答

21

此:

typedef int& ref; 
const ref error; 

沒有做什麼,你認爲它。考慮替代:

typedef int* pointer; 
typedef const pointer const_pointer; 

類型的const_pointerint* constconst int *。也就是說,當你說const T你說「做一個T是不可變的類型」;所以在前面的例子中,指針(不是指針)不可變。

不能提供參考constvolatile。這:

int& const x; 

是沒有意義的,所以將cv-qualifiers添加到引用不起作用。因此,error的類型爲int&。您無法爲其分配const int&


您的代碼還有其他問題。例如,這肯定是錯誤的:

template<class t> 
t const& check() 
{ 
    return t(); //return a temporary object 
} 

你在做什麼這裏返回到臨時對象當函數返回從而結束其生命週期的參考。也就是說,如果你使用它,你會得到未定義的行爲,因爲在referand中沒有對象。這絕不是優於:

template<class t> 
t const& check() 
{ 
    T x = T(); 
    return x; // return a local...bang you're dead 
}  

一個更好的測試將是:

template<class T> 
T check() 
{ 
    return T(); 
} 

函數的返回值是一個臨時的,所以你仍然可以測試你的確可以綁定的臨時恆定引用。

+0

好答案。 +1 :) – 2010-09-27 08:17:28

+0

謝謝。 :) – GManNickG 2010-09-27 08:21:56

7

你的代碼給出錯誤,因爲在const ref errorconst預選賽只是忽略,因爲8.3.2/1

Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument(14.3), in which case the cv-qualifiers are ignored.`

所以error的類型爲int&沒有const int&

0

這編譯:

 
typedef const int& ref; 
ref error = check<int>(); 

VC++編譯器給你的錯誤的一些解釋:預選賽應用於引用類型;忽略。引用類型必須聲明爲常量,以後不能再應用const。

8

因爲英語語法的作用方式,對講英語的人來說這是一個非常常見的錯誤。

我認爲這是非常不幸的是,C++語法將允許兩個:

const int // immutable int 
int const // immutable int 

具有相同的含義。

它不會使它更容易,真的,而不是組合的,因爲:

const int* // mutable pointer to immutable int 
int* const // immutable pointer to mutable int 

當然不具有相同的含義。

不幸的是,對你而言,這是什麼在踢,因爲@GMan解釋道。

如果要避免這種錯誤,在未來,承擔他們的排位賽你的類型(constvolatile)的習慣,那麼你就可以治療typedef爲簡單的文本替換。

3

爲了保持與Right Left Rule的一致性,我更喜歡使用'cv'限定符。

在你的榜樣,我會寫const ref error = check<int>();像這樣

ref const error = check<int>(); // parsed as error is a const reference to an integer 

由於@Prasoon Saurav指出,當通過typedef的介紹因爲@GMan還表示,CV預選賽被忽略,即CV合格引用是不合格的。

因此,聲明如下所示,這當然是一個錯誤。

int &error = check<int>(); 

查看this瞭解更多信息。

+1

由於帖子中給出的鏈接,這值得+1。 – 2010-09-27 10:00:03