Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

& после объявления функции в классе


class A
{
public:
    void f() &;
};


Что означает & после объявления функции?
    


Ответы

Ответ 1



Это означает, что функция может быть вызвана для 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 & )

Комментариев нет:

Отправить комментарий