Идеальная пересылка в C ++ 03 - PullRequest
       24

Идеальная пересылка в C ++ 03

23 голосов
/ 28 августа 2010

Если у вас есть эта функция

template<typename T> f(T&);

А затем попробуйте назвать его, скажем, значением r, например

f(1);

Почему T не может быть выведен как const int, что делает аргумент const int & и, следовательно, привязывается к r-значению?

Ответы [ 2 ]

22 голосов
/ 28 августа 2010

Это упоминается как потенциальное решение в документе , на который я ссылался в недавнем вопросе C ++ 0x о пересылке .

Это будет работают довольно хорошо, но это нарушает существующий код.Обратите внимание (прямо из документа):

template<class A1> void f(A1 & a1)
{
    std::cout << 1 << std::endl;
}

void f(long const &)
{
    std::cout << 2 << std::endl;
}

int main()
{
    f(5);              // prints 2 under the current rules, 1 after the change
    int const n(5);
    f(n);              // 1 in both cases
}

Или

// helper function in a header

template<class T> void something(T & t) // #1
{
    t.something();
}

// source

#include <vector>

void something(bool) // #2
{
}

int main()
{
    std::vector<bool> v(5);

    // resolves to #2 under the current rules, #1 after the change
    something(v[0]);
}

Также не удается переслать категорию значений (lvalue или rvalue), что не является большой проблемой вC ++ 03.Но поскольку это исправление можно было сделать только во время C ++ 0x, мы бы эффективно исключали себя из ссылок на rvalue при пересылке (плохо).Мы должны стремиться к лучшему решению.

1 голос
/ 28 августа 2010

Это так, но только если вы объявите f, чтобы взять T const &.

template <typename T> void f(T &);
template <typename T> void g(T const &);

void x() { f(1); }  // error: invalid initialization of non-const reference
void y() { g(1); }  // no error

И если вы объявите и f(T &) и f(T const &), это 'Я выберу константный:

template <typename T> void f(T &);
template <typename T> void f(T const &);

void x() { f(1); } // no error, calls f(T const &)

Теперь, может быть, вы говорите «в первом примере, почему он генерирует временный тип int для вызова f, когда он мог бы сгенерировать временный объект типа const int и заставить код скомпилироваться? ». Лучший ответ, который у меня есть для вас, заключается в том, что это будет несовместимо с поведением разрешения перегрузки, когда аргумент не является целочисленной константой.

...