2017-04-18 30 views
1

我是新來的C++模板和從C++ Templates The Complete Guide學習。 第二章有函數從參數中找到最大值。請看下面的代碼。使用模板查找最大值

#include <iostream> 

#define PRINT(x) std::cout<<#x<<":"<<x<<std::endl; 
template <typename T> 
inline T const& max(T const& a,T const& b) 
{ 
    return a>b?a:b; 
} 
int main(){ 
    int a=4; 
    PRINT(a); 
    PRINT(&a); 
    double b=3.1; 
    PRINT(b); 
    PRINT(&b); 
    double const & c = ::max<double>(a,b); 
    PRINT(c); 
    PRINT(&c); 
    return 0; 
} 

輸出。

一:4 &一個:0x7ffe1522731c

B:3.1 & B:0x7ffe15227320

C:4 & C:0x7ffe15227328

我不明白,爲什麼地址&a&c不一樣嗎?

回答

0

這是不特定模板,同樣的情況沒有他們。

的根本原因是C++的引用不是智能指針。他們不會自動管理內存。

具體來說,這裏所發生的是,你傳遞給int a=4max<double>(double const& a, double const& b)。由於存在類型不匹配,並且max承諾無論如何都不會更改這些值(const引用),所以C++會生成一個臨時值 double,值爲4.0。這個臨時生命到結尾的完整表達式,換句話說,直到該行末尾的分號。

這很不幸。該行是double const& c的初始化。因此,c被初始化爲對臨時4.0的引用,並且在初始化之後臨時消失立即

您現在可以參考前雙。沒有更多。它正在尋找峽灣。

特別是,在下一行嘗試使用c是未定義行爲,並且可能發生任何事情。正確的解決辦法是讓max<double>返回double。這是另一個價值。並且由於4.0 > 3.1,您將收回4.0。現在,參考const double& c會綁定到使用該值4.0初始化的另一個臨時值。

規則:結合一個臨時到const&臨時的壽命延伸到該const&壽命和僅該特定參考。用第一個引用初始化第二個引用不會像智能指針那樣工作,並且不會延長臨時的生命週期。

1

如何可能這是一樣的嗎?隨着max<double>你說的那個模板類型Tdouble,這意味着它返回到double參考。但是aint,它被轉換爲double

max<double>返回的引用是對創建的臨時值的引用,用於存儲轉換後的值a

,必須在所有的工作,因爲你必須const,延長臨時值的壽命引用。

-1

由於

double const & c = 

告訴編譯器分配足夠的存儲器以適應雙常量&,然後立刻通過分配max的值佔據。這是一個定義,而不是一個聲明。

+0

我很確定這不會發生什麼。有(最喜歡)沒有分配,也沒有分配。你也是混合類型'double const&'不是'double',所以它不能保存'max'的值。它可以保存對max返回的值的引用。轉換髮生在傳遞'a'作爲參數時,而不是返回結果。 – luk32

+1

哎呀,你是對的。我錯過了a是一個整數! –

0

你有a定義爲int

int a=4; 

max函數返回double。它位於不同的地址,並且結果可能是潛在的意外行爲。

+0

「從最大函數返回爲」double「。」你可能想要檢查它,它返回爲'double const&'。這是至關重要的。問題不僅僅是意外行爲,而是未定義行爲。 – MSalters