2015-07-03 11 views
25

Próbując skompilować ten prosty Klasa:Dlaczego decltype nie widzi deklaracji członka?

#include <vector> 
struct M 
{ 
// interface 
    auto begin() -> decltype(identities.begin()) 
    { 
     return identities.begin(); 
    } 
// implementation 
private: 
    std::vector<int> identities; 
}; 

powoduje błąd:

$ g++-510 where.cpp -std=c++11 
where.cpp:57:35: error: ‘struct M’ has no member named ‘identities’ 
    auto begin() ->decltype(this->identities.begin()) 
           ^
where.cpp:57:35: error: ‘struct M’ has no member named ‘identities’ 

$ clang++ where.cpp -std=c++11 -Wall -pedantic -Wextra 
where.cpp:57:35: error: no member named 'identities' in 'M' 
    auto begin() ->decltype(this->identities.begin()) 
          ~~~~^

Dlaczego nie decltype zobaczyć element klasy?

+0

w międzyczasie znalazłem obejście: zadeklarować zmienną składową przed użycie 'decltype'. Ale czy ktoś może podać standard, który nakazuje takie zachowanie? Czy jest to po prostu łatwiejsze dla twórców kompilatorów? – Bulletmagnet

+1

Duplikat http://stackoverflow.com/q/12362888/866732? – WiSaGaN

+0

Nie sądzę, że to duplikat, członek jest zadeklarowany powyżej funkcji tam. – TartanLlama

Odpowiedz

22

Z N3337 [basic.lookup.unqual]/7:

A name used in the definition of a class X outside of a member function body or nested class definition shall be declared in one of the following ways:

  • before its use in class X or be a member of a base class of X, or...

ponieważ typ powrotu spływu części funkcja deklaracja zamiast definicja, nie może patrzeć w przyszłość, aby zobaczyć, co jeszcze jest zadeklarowane w klasie, więc musisz zadeklarować tego członka powyżej deklaracji funkcji.

2

Przenoszenie zgłoszenia członu przed funkcją tak:

#include <vector> 
struct M 
{ 
    // implementation 
    private: 
     std::vector<int> identities; 
    public:  
    // interface 
    auto begin() -> decltype(identities.begin()) 
    { 
     return identities.begin(); 
    } 


}; 
16

Jeśli C++ 14 jest dostępny, można pominąć spływu typ zwracany, unikając odwoływania członka spoza ciała funkcji, a także czyniąc kod bardziej kompaktowy:

auto begin() { 
    return identities.begin(); 
} 

Na ogół jest to bardziej poprawne użycie decltype(auto) dla takich metod spedycji, więc rodzaj powrotu może być punktem odniesienia, chociaż w tym konkretnym przypadku jest to ten sam (dzięki @Nawaz):

decltype(auto) begin() { 
    return identities.begin(); 
} 
+0

Niestety, mamy już szczęście, aby móc używać C++ 11 (jedyny projekt w mojej firmie), więc będę musiał pójść z TartanLlama :) – Bulletmagnet

+0

Myślę, że powinien to być 'decltype (auto)', chociaż w tym przypadku zadziała "auto". – Nawaz

+1

@Nawaz dzięki za wskazanie tego, zaktualizowałem odpowiedź. –

Powiązane problemy