2017-12-02 334 views
9

How do I write a lambda expression that looks like a method? numaralı telefonu yanıtlarken, C++ 17, captureless lambda'ların işlev işaretçisi türüne göre constexpr dönüşüm işlecine sahip olduğu gerçeği istismar ederek kaptureless bir lambdayı üye işlev göstergesine dönüştürmeye çalıştım.Bir C++ 17 kapturusuz lambda constexpr dönüşüm işlecinin sonucunu bir işlev işaretçisi şablonu türünde olmayan bağımsız değişken olarak kullanabilir miyim?

Yani bir sorun aşağı kaynar ile geldi: (5.0.0 beri)

template<void(*)()> struct A{}; 

int main() 
{ 
    A<static_cast<void(*)()>([]{})>{}; // 1 

    constexpr auto fp = static_cast<void(*)()>([]{}); 
    A<fp>{}; // 2 
} 

Şimdi, bu clang içinde derler ama gcc (> = 7.2) şikayet:

error: lambda-expression in template-argument 
    A<static_cast<void(*)()>([]{ /*whatever*/ })>{}; // 1 
          ^
error: 'main()::<lambda()>::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::<lambda()>::_FUN()' has no linkage 
    A<fp>{}; // 2 

Soru şu: kim haklı?

+1

Constexpr yerel değişkenlerini kullanan daha basit bir örnek bulunmalıdır, değil mi? – Yakk

+0

@Yakk, tamamlandı; Bu orijinal kodla tamamen eşdeğer değil ... ya da değil mi? –

+0

Tam olarak ne yapmaya çalıştığınızı ve bunun neden gerekli olduğunu merak etmemde yardımcı olamıyorum. –

cevap

3

Bu, 83258 dosyalanmış bir gcc hatasıdır.

C++ 14'te, işaretçi türü olmayan şablon parametreleri için linkage requirement kullanıyorduk. Ancak C++ 17'de (N4268 sonucu), parametrenin yalnızca birkaç tane kısıtlama olmak üzere doğru tipte converted constant expression olması gerekir (bunların hiçbiri burada alakalı değildir). fp'u oluşturabildiğimizde, bunu bir şablon parametresi olarak kullanabilmeliyiz.