2017-09-29 87 views
5

Piszę kod, w którym typ zwracany funkcji jest dość skomplikowany. Chciałbym użyć auto do dedukcji z typu zwrotu, ale to oczywiście nie jest możliwe w deklaracji forward. Więc miałem nadzieję, że przynajmniej tylko powielać zawartości instrukcji return i wykonaj następujące czynności,Ścieżka między wstecznym typem a odjęciem zwracanym

int q = 5; // veeery complicated type 

/* Declaration - the best we can do */ 
auto f() -> decltype(q); 

/* Later, in a different file */  
auto f() { 
    return q; 
} 

To daje następujący błąd w GCC 7

error: ambiguating new declaration of ‘auto f()’ 
note: old declaration ‘int f()’ 

Oczywiście mógłbym powtórzyć

auto f() -> decltype(q) { 
    return q; 
} 

w definicji (która działa), ale dlaczego powinienem potrzebować, gdy typ zwrotu jest już jednoznacznie podany przez instrukcję return? W jaki sposób typ f w mojej definicji jest ostatecznie bardziej niejednoznaczny niż int f()?

+0

nie jest standardowym guru, ale co to jest kompilator robić jeśli , zgodnie z aktualną definicją funkcji, typ końcowy i typ wyprowadzony "auto" nie pasują do siebie? Myślę, że to jest powód, dla którego gcc to zgłosi. – YiFei

+1

Spodziewałam się, że po prostu mi powie, że to nie pasuje. To, czy dwa typy są takie same, czy nie powinno być łatwe do odpowiedzi. Ale teraz, gdy wspomniałeś o tym, całkiem interesująco, błąd spowodowany przez 'int f(); long f() {return 1; } 'jest sformułowane tak samo! –

+0

Zgodzę się z tobą. Chciałbym również wiedzieć, czy istnieje standardowe odniesienie, które wyraźnie stwierdza, że ​​typu zwracanego 'auto' nie można spasować z konkretną funkcją typu return (nawet jeśli pasują do siebie). – YiFei

Odpowiedz

8

Problem polega na tym, że powrót na końcu nie jest tym samym, co czysto wyprowadzony typ zwrotu. W [dcl.spec.auto]/2

[...] Jeśli declarator funkcja obejmuje zwrotny typu wleczonego (8.3.5), która określa typ deklarowanej powrotną funkcji

Więc

auto f() -> decltype(q); 

jest naprawdę

int f(); 

, który różni się od

auto f() 

Jest też [dcl.spec.auto]/13

Redeclarations lub specjalności funkcji lub szablon funkcji o deklarowanej typu jednokierunkowy, który jest stosowany typ zastępczy Shall również użyj tego symbolu zastępczego, a nie typu wyprowadzonego. [Przykład:

auto f(); 
auto f() { return 42; } // return type is int 
auto f();    // OK 
int f();     // error, cannot be overloaded with auto f() 
decltype(auto) f();  // error, auto and decltype(auto) don’t match 

Który rodzaj przeciwieństwem tego, co się tu dzieje, ale nie dalej przykładem, że nie jest to dozwolone