Функции друзей с параметрами const - PullRequest
2 голосов
/ 22 апреля 2020

Я узнал, что для создания функции-друга функция-член должна быть явно объявлена ​​в прилагаемой области видимости или принять аргумент своего класса. Тем не менее, это, похоже, предостережение, я не смог понять. Почему звонок на f1(99) не работает?

class X { 
  public:
    X(int i) {
      std::cout << "Ctor called" << std::endl;
    }
    friend int f1(X&);
    friend int f2(const X&);
    friend int f3(X);
};
int f1(X& a) {
  std::cout << "non-const called" << std::endl;
}
int f2(const X& a) {
  std::cout << "const called" << std::endl;
}
int f3(X a) {
  std::cout << "object called" << std::endl;
}   

int main() {
  f1(99);
  f2(99);
  f3(99);
}

1 Ответ

2 голосов
/ 22 апреля 2020

Вы вызываете функции с аргументом 99; но все функции ожидают X. 99 может преобразовываться в X неявно, но преобразованный X является временным объектом и не может быть привязан к lvalue-reference для non-const.

Временный объект может быть связан с lvalue-ссылкой на const (а также с rvalue-ссылкой начиная с C ++ 11), тогда f2(99); работает. И это может быть скопировано в параметр f3, тогда f3(99) тоже работает.

Эффекты эталонной инициализации:

  • В противном случае, если ссылка является lvalue ссылкой на энергонезависимый const-квалифицированный тип or rvalue reference (since C++11):

    • В противном случае объект неявно преобразуется в T. Ссылка привязывается к результату преобразования (after materializing a temporary) (since C++17) , Если объект (или, если преобразование выполняется с помощью пользовательского преобразования, результата функции преобразования) имеет тип T или является производным от T, он должен быть в равной или меньшей степени cv-квалифицированным, чем T , and, if the reference is an rvalue reference, must not be an lvalue (since C++11).
...