vs gcc. en aşağıdaki struct
türleri vardır varsayalım:Aşırı yükleme yapılar - clang
struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
b
ve c
bir auto
parametresini kullanarak genel bir lambda'da "yakalanmış" iken ben, bir aşırı yük açıkça a
kolları lambdas dışına set oluşturmak istiyorum:
auto ol = overload([](a x) { x.foo(); },
[](auto x){ x.bar(); })
ben çağırmak ol(a{})
:
clang ++, derleme ve beklendiği gibi davranır:
a
, "birinci" lambda eşleşirken,b
vec
, ikinci olanı eşleştirir.gr ++ aşağıdaki hata ile, derlenmeyecektir:
error: 'struct a' has no member named 'bar' [](auto x){ x.bar(); }; ~~^~~
derleyici İlki yolu iyi bir eşleşme olsa da ikinci lambda örneğini çalışır gibi görünüyor. Umarım bu bir hatadır, çünkü bana görünmez gibi geliyor. Ben lambda'lar
s0
kabaca eşdeğer olması beklenebilirstruct s0 { auto operator()(a x) const { x.foo(); } }; struct s1 { template <typename T> auto operator()(T x) const { x.bar(); } }; auto os = overload(s0{}, s1{}); os(a{}); // OK!
ve: yerine lambda Bazı eski moda
struct
örneklerini kullanmak ifadelerde ise
Not hem derleyiciler düzgün çalışması s1
, bu daha da şaşırtıcı.
Bu
ben aşırı yük setini üreten ediyorum yoludur:template <typename... Fs>
struct overloader : Fs...
{
template <typename... FFwds>
overloader(FFwds&&... fs) : Fs{std::forward<FFwds>(fs)}...
{
}
using Fs::operator()...;
};
template <typename... Fs>
auto overload(Fs&&... fs)
{
return overloader<std::decay_t<Fs>...>{std::forward<Fs>(fs)...};
}
Ve burada derleyici arasında farklı davranış gösteren bir live example on gcc.godbolt.org
bu.
Bu bir g ++ hatası mı? Veya standart olarak lambdaların bu durumda struct
örneğinden farklı davranmasını sağlayan bir şey var mı?
Huh, ne zaman kullandı <> ...'standart girmek? C++ 17? –
@NirFriedman Yep, C++ 17 sayesinde, [P0195] sayesinde (http://wg21.link/p0195) – Barry
Bir kenara: 'aşırı yüke' argüman olarak işlev göstergelerini kullanabilmek güzeldir. Bunu yapmak için, ': Fs ... 'yerine:' some_magic' ... 'ile,' 'some_magic' işlev işaretleyicilerini algılar ve onu depolayan bir sınıfa ve onun dışındaki her şeyi tek başına bırakır. (Ancak bu aşırı yüklenme, basitleştirilmiş bir MCVE'dur, bu durumda bunu görmezden gelir) –
Yakk