2016-05-04 9 views
10

g ++ 6.1 został niedawno wprowadzony do repozytoriów testowych Arch Linux, a niektóre z mojego kodu, które zostały skompilowane z g ++ 5.3.0 już się nie kompilują. Zrobiłem minimalny przykład:Możliwe std :: regresja z g ++ 6.1 - błąd lub zamierzone zachowanie?

gcc.godbolt.org link

// This code compiles with g++ 5.3.0 
// This does not compile with g++ 6.1 

#include <type_traits> 
#include <utility> 
#include <tuple> 

#define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__) 

struct sinker 
{ 
    template <typename T> 
    void sink(T&) 
    { 
    } 
}; 

template <typename T, typename TF> 
void caller(T& v, TF&& f) 
{ 
    sinker s; 
    f(s, v); 
} 

template <typename T> 
void interface(T& v) 
{ 
    return caller(v, [](auto& xs, auto&& xv) -> decltype(auto) 
     { 
      xs.sink(FWD(xv)); 
     }); 
} 

int main() 
{ 
    int x = 0; 
    interface(x); 
} 

To jest komunikat błędu:

: In instantiation of ‘get_impl(T&)::<lambda(auto:1&, auto:2&&)> [with auto:1 = sinker; auto:2 = int; T = int]’: 
:25:58: required by substitution of ‘template<class auto:1, class auto:2> get_impl(T&) 
     [with T = int]::<lambda(auto:1&, auto:2&&)>::operator 
     decltype (((get_impl(T&) [with T = int]::<lambda(auto:1&, auto:2&&)>)0u).operator()(static_cast<auto:1&>(<anonymous>), 
     static_cast<auto:2&&>(<anonymous>))) (*)(auto:1&, auto:2&&)() const [with auto:1 = sinker; auto:2 = int]’ 
:19:6: required from ‘void chunk_fn_impl(T&, TF&&) [with T = int; TF = get_impl(T&) [with T = int]::<lambda(auto:1&, auto:2&&)>]’ 
:25:25: required from ‘void get_impl(T&) [with T = int]’ 
:36:15: required from here 
:27:13: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’ 
      xs.sink(FWD(md)); 
      ^~ 
:10:10: note: initializing argument 1 of ‘void sinker::sink(T&) [with T = int]’ 
    void sink(T&) 
      ^~~~ 

zmienia:

return caller(v, [](auto& xs, auto&& xv) -> decltype(auto) 

do:

return caller(v, [](auto& xs, auto& xv) -> decltype(auto) 

pozwala na pomyślne skompilowanie kodu.


Nie rozumiem dlaczego ten błąd się dzieje, jak xv jest doskonale przekazane, a połączenie FWD(xv) powinna produkować lwartości odniesienia. Zauważ, że kod działał zgodnie z przeznaczeniem w g ++ 5.3.0 i clang ++ 3.7.

gcc.godbolt.org link

(Spróbuj zestawiania z wieloma wersjami g ++ i zmieniając auto&& do auto&.)

Czy to jest g ++ 6.1 bug? A może kod niepoprawnie kompilował się z poprzednimi wersjami g ++ i clang ++?

+0

Nie ma nic wspólnego z 'forward'. Wygląda to jak błąd frontendu. –

+0

To 'auto &&' oznacza, że ​​lambda jest szablonem, który wymaga dedukcji typu argumentu. Ale tak samo jest z "dzwoniącym". Nie rozumiem, jak można to skompilować, powinno ono tkwić w nieskończenie rekurencyjnym odjęciu argumentów. Przynajmniej zgodnie z moim prymitywnym zrozumieniem lambdas z 'auto &&'. Ktoś wyjaśnij, dlaczego to powinno działać. – sp2danny

+0

@ T.C. zgłaszane jako [błąd 70942] (https://gc.gnu.org/bugzilla/show_bug.cgi?id=70942) –

Odpowiedz

1

To jest błąd w interfejsie G ++: problem został zgłoszony jako bug 70942.

Powiązane problemy