2016-12-16 27 views
10

Rozważmy przykład:Dlaczego lambda, po rzutowaniu na wskaźnik funkcji, może być używana w kontekście constexpr?

template <void (*Foo)()> 
struct S { 
}; 

int main() { 
    struct A { 
     static void x() { } 
    }; 
    S<&A::x> s; 
} 

Kod kompiluje w brzękiem, gcc twierdzą, że x nie posiada powiązań ... dla zupełnie podobny przykład tylko przy użyciu wyrażenia lambda:

template <void (*Foo)()> 
struct S { 
}; 

int main() { 
    auto lambda = []{}; 
    S<+lambda> s; 
} 

zarówno gcc i brzęk zgadza się nie skompilować kod: zgodnie z OWP funkcji zwracany przez jednoargumentowego + nie ma powiązania, dzyń stany w przeciwieństwie że oddane do funkcji operatora nie jest zadeklarowany jako constexpr. Czy są jakieś powody, aby odrzucić rzutowanie lambda do wskaźnika funkcji do użycia w kontekście constexpr?

Znajdź poniżej błędów produkowanych przez kompilatory i pokazy na żywo:

gcc:

prog.cc:7:14: error: 'main()::::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::::_FUN()' has no linkage

clang:

prog.cc:7:8: note: non-constexpr function 'operator void (*)()' cannot be used in a constant expression

+2

'lambda' nie łączników, ze względu http://eel.is/c++draft/basic.link#8 i oczywiście' operatora() '' constexpr' nie jest, więc jest to kwestia jaki błąd jest wysyłany jako pierwszy - czy jestem w błędzie? – skypjack

+0

@skypjack To samo zawarcie Przyszedłem po kawałku wyszukiwanie wokół (jest to ten sam powód, dlaczego 'A' ma powiązania). Poza tym typy, które nie mają powiązania, nie mogą być używane jako argument szablonu. –

Odpowiedz

10

Clang hasn't implemented constexpr lambdas yet.

GCC jest tyle innych sposobów. [temp.arg.nontype]/2 's tylko interesujące ograniczenie jest to, że argument będzie stałym wyrażeniem. Ale [expr.const]/(5.2) czyni go jednym, więc jest to całkowicie poprawne. Być może GCC nie wdrożył jeszcze N4198, co wyeliminowało wymóg połączenia.

Należy zauważyć, że zarówno constexpr lambdas i bez powiązania argumenty szablonu wskaźnik funkcji są pocztowe C++ 14 funkcji.

+0

Więc kod powinien być ważny od C++ 14? –

+2

Nie, nie są też częścią 'constexpr'lambdas w C++ 14, ani też N4198 nie został włączony. – Columbo

+0

Dzięki! Chciałem po prostu mieć pewność :) –