Странный C ++ шаблон и константная проблема - PullRequest
7 голосов
/ 16 сентября 2011

Я не понимаю, почему вывод этой программы Второй метод вместо Первый метод ...

#include <iostream>

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

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

class A
{
public:
    A(int a):_a(a){};
private:
    int _a;
    friend A operator+(const A& l, const A& r);
};

A operator+(const A& l, const A& r) {
friend 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+b);
}

Однако, когда я изменяю свою основную функцию на это:

int main ()
{
    A a=1;
    const A b=2;
    A c=a+b;
    assign(a,c);
}

Вывод Первый метод . Есть идеи?

Ответы [ 2 ]

15 голосов
/ 16 сентября 2011
assign( a, a+b );

Результатом a + b является rvalue-выражение типа A, которое создает временное значение, и вы не можете связать его с неконстантной ссылкой, поэтому оно получает const перегрузка, поскольку вам разрешено связывать константную ссылку с временным.

assign( a, c );

В этом случае подвыражение c является выражением lvalue , и вы можете связатьнеконстантная ссылка.В этом случае, поскольку неконстантная версия идеально подходит для T=A, она предпочтительнее, чем константная перегрузка, которая потребует преобразования второго аргумента из lvalue типа A в const lvalue типа A.

5 голосов
/ 16 сентября 2011

&t2 в ваших функциях использует ссылку.

Однако a+b не может быть привязан к нормальной ссылке, поэтому он должен быть передан как const ссылка.

Во втором main вы передаете правильное значение l, поэтому оно может быть изменено функцией (и, следовательно, const может изменить значение).

Это мое предположение, по крайней мере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...