Идеальная пересылка в C++03
Если у вас есть эта функция
template<typename T> f(T&);
А затем попробуйте позвонить с помощью, скажем, rvalue, как
f(1);
Почему T просто не выводится как const int, делая аргумент const int& и, таким образом, привязываемым к r-значению?
2 ответа
Это упоминается в качестве потенциального решения в документе, на который я ссылался в недавнем вопросе о переадресации 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 при пересылке (плохо). Мы должны стремиться к лучшему решению.
Это так, но только если вы объявите 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
и сделал код компиляцией? ". Лучший ответ, который у меня есть для вас, это то, что это будет несовместимо с поведением разрешения перегрузки, когда аргумент не является целочисленной константой.