class A
{
public:
void f() &;
};
Что означает & после объявления функции?
Ответ
Это означает, что функция может быть вызвана для lvalue объекта класса A
Рассмотрите следующий пример
#include
class A
{
public:
void f() & { std::cout << "A::f() &" << std::endl; }
void f() && { std::cout << "A::f() &&" << std::endl; }
};
int main()
{
A a;
a.f();
A().f();
}
Вывод на консоль этой программы
A::f() &
A::f() &&
В классе A функция f перегружена для lvale объектов класса A и для rvalue объектов класса A
В этой программе в предложении
a.f();
вызывается функция f для lvalue объекта a
В этом же предложении
A().f();
вызывается функция f для rvalue объекта A()
Другой пример.
#include
class A
{
public:
void f() const & { std::cout << "A::f() const &" << std::endl; }
void f() & { std::cout << "A::f() &" << std::endl; }
};
void h( const A &a )
{
a.f();
}
int main()
{
A a;
a.f();
h( a );
}
Вывод на консоль
A::f() &
A::f() const &
В этом примере класс A объявляет две перегруженные функции с именем f: одна для константных lvalue объектов, а другая для неконстантных lvalue объектов.
В предложении
a.f();
вызывается функция для неконстантных объектов, так как объект a не является константным.
Однако внутри функции h
h( a );
вызывается перегруженная функция для константных объектов, так как параметр функции является константой ссылкой.
Еще один пример.
Данная программа не будет компилироваться
#include
class A
{
public:
void f() & { std::cout << "A::f() &" << std::endl; }
};
int main()
{
A().f();
}
Потому что rvalue не может быть привязана к неконстантной ссылке.
Однако если объявить функцию как имеющую дело с константной ссылкой, то программа будет компилироваться
#include
class A
{
public:
void f() const & { std::cout << "A::f() const &" << std::endl; }
};
int main()
{
A().f();
}
Чтобы было более понятно, то можно представить эти функции следующим образом.
Каждая нестатическая функция-член класса имеет неявный параметр, который соответствует this
Поэтому данные две функции-члены класса
void f() const &
и
void f() &
концептуально выглядят как
void f( A * const & ) /*const &*/
и
void f( A * & ) /*&*/
Поэтому последнюю функцию нельзя вызывать для временных объектов типа A *, тогда как первую - можно, так как константная ссылка может привязыватья к временному объекту.
Вот пример, который упрощенно демонстрирует сказанное
#include
void f( int * const & ) { std::cout << "f( int * const & ) " << std::endl; }
void f( int * & ) { std::cout << "f( int * & )" << std::endl; }
int main()
{
int i = 10;
int *pi = &i;
f( pi );
f( &i );
}
Вывод на консоль:
f( int * & )
f( int * const & )
Комментариев нет:
Отправить комментарий