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 } } <br>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 } } <br>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 } } <br>int main() { A().f() } Потому что rvalue не может быть привязана к неконстантной ссылке. Однако если объявить функцию как имеющую дело с константной ссылкой, то программа будет компилироваться #include class A { public: void f() const & { std::cout << "A::f() const &" << std::endl } } <br>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 }<br>int main() { int i = 10 int *pi = &i f( pi ) f( &i ) } Вывод на консоль: f( int * & ) f( int * const & )