我發現了一個代碼段編譯和鐺+ 4(和軀幹)正常工作,但未能在G ++ 7(和軀幹)編譯。假設我有以下struct
類型:重載結構與模板調用操作和通用Lambda表達式 - GCC VS鐺
struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
我想創建一個過載設置出它處理a
明確lambda表達式,而b
和c
是「捕獲」用一個auto
參數的通用拉姆達:
auto ol = overload([](a x) { x.foo(); },
[](auto x){ x.bar(); })
當我調用ol(a{})
:
鐺++編譯和表現如預期:
a
「匹配」第一個lambda,而b
和c
匹配第二個。G ++無法編譯,並出現以下錯誤:
error: 'struct a' has no member named 'bar' [](auto x){ x.bar(); }; ~~^~~
看來,編譯器試圖實例,即使第一個是一個更好的方式比賽的第二拉姆達。希望這是一個錯誤,因爲它對我來說似乎不直觀。
注意兩種編譯器正常工作,如果不是lambda表達式我使用一些老式struct
實例:
struct 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!
我期望lambda表達式是大致相當於s0
和s1
,所以這更令人驚訝。
這是我生產的重載集合方式:
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)...};
}
而這裏的一個live example on gcc.godbolt.org
,顯示了編譯器的不同的行爲。
這是一個g ++的bug嗎?或者在這種情況下,標準中是否存在使lambda表現與struct
實例不同的東西?
呵呵,什麼時候使用<> ...'輸入標準? C++ 17? –
@NirFriedman是的,在C++ 17中,感謝[P0195](http://wg21.link/p0195) – Barry
另外:能夠將函數指針作爲'overload'參數是很好的。要做到這一點,用':some_magic ...'替換':Fs ...',其中'some_magic'檢測函數指針並將其映射到存儲它的類,以及其它所有內容。 (但是也許這個過載是一個簡化的MCVE,在這種情況下忽略這個) –
Yakk