2017-12-02 106 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.

İlgili konular