Разрешено ли компилятору выбирать const ref вместо ref во время разрешения перегрузки? - PullRequest
1 голос
/ 18 марта 2012

Некоторый фон:

Однажды я столкнулся с чем-то, что заставило меня задуматься о разрешении перегрузки в вызовах вложенных функций. Рассмотрим код ниже:

#include <iostream>

void printer(const int &a)
{
  std::cout << a << "\n";
}

const int& func(const int &a)
{
  std::cout << "const int& ";
  return a;
}

int& func(int &a)
{
  std::cout << "int& ";
  return a;
}

int main()
{
  int a = 42;
  const int b = 21;
  printer(func(a));
  printer(func(b));

  return 0;
}

Этот код печатает

int& 42
const int& 21

Итак, func (a), очевидно, видит, что a неконстантное int. Компилятор также должен видеть, что функция принтера хочет получить const int & аргумент. И существует функция (...), которая возвращает const int &. Я посмотрел на стандарт C ++, и он говорит, что const refs и refs считаются разными типами параметров (и именно поэтому он выбирает int & for func (a)).

К вопросу:

Разрешено ли компилятору использовать версию func (const int &) вместо func (int &) при вызове func (a)?

(Возможно, существует некоторая возможность оптимизации, если он видит, что результат передается функции, требующей const int & параметр.)

1 Ответ

5 голосов
/ 18 марта 2012

Разрешение перегрузки не учитывает тип возвращаемого значения. То есть он будет рассматривать только аргумент функции и различные перегрузки, независимо от того, как будет использоваться возвращаемое значение.

Для более явного теста рассмотрите возможность изменения неконстантной перегрузки на:

void func( int& ) {}

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

...