簡體   English   中英

C ++模板問題

[英]C++ Templates Question

有人可以解釋以下代碼的輸出嗎?

#include <iostream>

template <class T>
void assign(T& t1, T& t2){
    std::cout << "First method"<< std::endl;
    t1 = t2;
}

template <class T>
void assign(T& t1, const T& t2) {
    std::cout << "Second method"<< std::endl;
    t1 = t2;
}

class A
{
public:
    A(int a) : _a(a) {};

private:
    friend A operator+(const A& l, const A& r);

    int _a;
};

A operator+(const A& l, const A& r) 
{
    return A(l._a + r._a);
}

int main ()
{
    A a = 1;
    const A b = 2;

    assign(a, a);
    assign(a, b);
    assign(a, a + b);
}

輸出是

First method

Second method

Second method

我不明白為什么。 因為(a + b)不會返回const A對象,所以最后一次分配調用不應該激活第一個版本嗎?

(a + b)返回一個臨時對象,因此只能綁定到一個常量引用。

表達式不僅具有值和類型,而且具有值category 此類別可以是

  • 左值:這些表達式通常引用已聲明的對象,引用,函數或指針的取消引用結果。
  • xvalue:這些是生成未命名的rvalue引用的結果。 右值引用由T&&而非T& 它們是C ++ 11的概念,您可以在此處忽略它們。 僅出於完整性考慮而提及。
  • prvalue:這些是轉換為非引用類型(例如A(10) )或計算/指定值(例如422 + 3

左值引用需要一個左值表達式進行初始化。 即,以下內容無效:

A &x = A(10);

其背后的原因是,僅左值表達式所指的對象是適合且打算比僅在初始化期間存活更長時間的事物。 就像,聲明的對象一直存在,直到退出其塊(如果它是局部非靜態變量)或直到程序結束(如果在函數和類外部聲明)。 右值表達式A(10)引用初始化完成后已經死亡的對象。 而且,如果您說的是以下內容,那將毫無意義,因為像10這樣的純值根本沒有地址,但是引用要求它們綁定到某種身份,實際上,這是通過使用它們在編譯器內部的目標地址

int &x = 10; // makes totally no sense

但是對於const引用,C ++具有后門。 當使用prvalue初始化時,如果表達式引用對象,則const lvalue引用將自動延長對象的生存期。 如果表達式具有非對象值,則C ++會使用該表達式的值創建一個臨時對象,並延長該臨時對象的壽命,並將引用綁定到該臨時對象:

// lifetime of the temporary object is lengthened
A const& x = A(10); 

// lifetime of the automatically created temporary object is lengthened
int const& x = 10; 

您的情況如何?

現在,由於您提供了一個臨時對象,因此您的情況下的編譯器將選擇具有A const&參數類型而不是A&參數類型的版本。

a+b返回一個臨時變量,如果允許您捕獲對它的非const引用,則可以對其進行更改,然后怎么辦? 臨時范圍超出范圍,對它所做的更改永遠不會被應用程序捕獲。 在C ++ 03中,臨時變量將綁定到const引用類型。

順便說一下,這與模板無關。 重寫示例以使用直接的“ A”,您將觀察到相同的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM