Возможна ли регрессия std::forward с g++ 6.1 - ошибка или предполагаемое поведение?

g++ 6.1 была недавно введена в тестовые репозитории Arch Linux, и часть моего кода, успешно скомпилированного с g++ 5.3.0, больше не компилируется. Я сделал минимальный пример:

gcc.godbolt.org ссылка

// 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);
}

Это сообщенная ошибка:

: 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&)
          ^~~~

Изменение:

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

чтобы:

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

позволяет успешно компилировать код.


Я не понимаю, почему эта ошибка происходит, так как xv в настоящее время идеально направлен и FWD(xv) вызов должен производить ссылку на lvalue. Обратите внимание, что код работал так, как задумано в g++ 5.3.0 и clang ++ 3.7.

gcc.godbolt.org ссылка

(Попробуйте скомпилировать с несколькими версиями g ++ и изменить auto&& в auto& .)

Это ошибка g++ 6.1? Или код неправильно компилировался с предыдущими версиями g ++ и clang++?

1 ответ

Решение

Это ошибка внешнего интерфейса g++: проблема была зарегистрирована как ошибка 70942.

Другие вопросы по тегам