2016-09-25 14 views
8

Po pierwsze, NIE mówię o łańcuchach konstruktorów C++ 11 zwanych delegacją konstruktora.Członek wywołujący łańcuch działa poza konstruktorem nazwanego obiektu.

Funkcje składowe klasy mogą zwracać odwołanie do siebie (klasy), więc wywołania funkcji mogą być powiązane. (Tak jak operator cout < < działa, aby umożliwić wywoływanie łańcucha.)

Podczas tworzenia obiektu anonimowego, takie wywołania łańcucha mogą wystąpić poza konstruktorem.

Czy wywołania łańcuchowe mogą być wykonywane poza konstruktorem nazwanego obiektu? Linie dla "foo a" i "foo b" poniżej nie kompilują się, więc zastanawiam się, czy istnieje inna składnia.

#include <iostream> 
using namespace std; 

class foo { 
    public: 
     foo(int x) : val{x} { }; 
     foo& inc() { ++val; return *this; } 
     int getVal() { return val; }; 
    private: 
     int val; 
}; 

int main() { 
    cout << foo(1).inc().getVal() << endl; // prints 2 
    cout << foo{2}.inc().inc().inc().inc().getVal() << endl; // prints 6 
    foo a(3).inc(); // error: expected ‘,’ or ‘;’ before ‘.’ token 
    foo b{4}.inc(); // error: expected ‘,’ or ‘;’ before ‘.’ token 
    cout << a.getVal() << endl; 
    cout << b.getVal() << endl; 
} 
+3

zasadzie „nie”. 'foo (1)' jest wyrażeniem, 'foo a (3)' nie jest wyrażeniem. Będziesz musiał napisać 'foo a (3); a.inc(); ' –

Odpowiedz

2

można uzyskać podobny efekt, łańcuchy inicjalizacji:

foo c = foo{5}.inc().inc(); 

zaskakujące, że mój kompilator zoptymalizowane do stałej, więc nie jest to kara wydajność.

2

Myślę, że jest to jedna z zalet stylu Almost Always Auto. Jeśli jesteś w zwyczaju pisania:

auto a = foo{3}; 

następnie można Połączenia łańcuchowe bez niekonsekwencji:

auto a = foo{3}.inc(); 
Powiązane problemy