2013-05-21 16 views
9

Wystąpił błąd podczas kompilowania poniżej kodu.decltype jako typ zwrotu w funkcji członka klasy

struct B{ 
    double operator()(){ 
     return 1.0; 
    } 
}; 

struct A { 
    auto func() -> decltype(b()) 
    { 
     return b(); 
    } 

    B b; 
}; 

Jednak, jeśli zmienię organizację A, kompiluje się.

gcc 4.8 powiedział, że "b" nie został zadeklarowany w tym zakresie.

struct A { 
    B b; 
    auto func() -> decltype(b()) 
    { 
     return b(); 
    } 
}; 

Co jest nie tak z pierwszym?

+0

Należy bardziej szczegółowo, o co starasz się zapytać. "Czy to jest ważne?" może być nieco zbyt ogólnikowe, aby społeczność w pełni zrozumiała, o co prosisz. –

+0

@JeffWolski: Tak, zgadzam się, więc poprawiłem brzmienie :) – Sungmin

Odpowiedz

8

Definicja class jest przetwarzana w dwóch przebiegach: najpierw zbierane są deklaracje członkowskie, w tym funkcje podpisy, a następnie analizowane są ciała definicji.

Ciało funkcji ma zatem dostęp do wszystkich deklaracji członkowskich, w tym kolejnych, ale prototyp funkcji widzi tylko poprzednie deklaracje.

+0

Typ późnego zwrotu nie jest jednak częścią ciała/definicji. Na przykład. może pojawić się tylko w deklaracji. –

+0

Tak. Użycie 'auto ... ->' przenosi typ zwracany syntaktycznie i pozwala używać nazw parametrów w typie zwracanym, ale to jedyna różnica. – Potatoswatter

9

Czy jest ważna?

Twój ostatni przykład jest dobrze sformułowany, a pierwszy nie jest (więc GCC jest poprawny).

Paragraf 3.4.1/7 na imię niewykwalifikowanego odnośnika określa:

nazwa używana w definicji klasy Xzewnątrz ciała funkcji członek, domyślnym argumentem klamra-lub- równych initializer nie-statyczne członka danych lub zagnieżdżone klasy definicja zgłasza się w jednym z następujących sposobów :

- przed jego zastosowaniem w klasie X lub być członkiem klasy podstawowej X (10.2), lub

- [...]

A co za tym idzie są inne warunki, które nie mają zastosowania w Twój przypadek.

1

Można również uzyskać go do pracy tak:

struct B 
{ 
    double operator()() 
    { 
     return 1.0; 
    } 
}; 

// my implementation does not have std::declval 
template < typename T > T&& declval(); 

struct A 
{ 
    B b; 
    auto func() -> decltype(declval<B>().operator()()) 
    { 
     return b(); 
    } 
}; 

edit: lub od B jest w zakresie już zresztą nie ma potrzeby auto, -> decltype i declval

struct A 
{ 
    B b; 
    decltype(Q()()) func() 
    { 
     return b(); 
    } 
}; 
+0

Dzięki, właśnie to chciałem zrobić. Nie wiedziałem o deklvalacji. Nie była to jednak bezpośrednia odpowiedź na moje pytanie. Więc wybrałem inny. To bardzo mi pomaga:) – Sungmin

Powiązane problemy