c++selfperfect-forwardingc++23forwarding-reference

std::forward_like error with clang and deducing this


I'm experimenting with deducing this in order to simplify a code base. I'm getting an issue with a straightforward test:

#include <iostream>
#include <type_traits>
#include <utility>

class S {
   public:
    auto Get(this auto&& self) -> auto&& {
        return std::forward_like<decltype(self)>(self.val);
    }

   private:
    int val{0};
};

int main() {
    S const s;
    std::cout << std::is_rvalue_reference_v<decltype(s.Get())> << '\n';
    std::cout << std::is_const_v<
                     std::remove_reference_t<decltype(s.Get())>> << '\n';
    std::cout
        << std::is_rvalue_reference_v<decltype(std::move(s).Get())> << '\n';
    std::cout
        << std::is_const_v<
               std::remove_reference_t<decltype(std::move(s).Get())>> << '\n';
}

LIVE

msvc and gcc are giving the expected result, but not clang, that gives:

 error: function 'forward_like<const S &, const int &>' with deduced return type cannot be used before it is defined
note: in instantiation of function template specialization 'S::Get<const S &>' requested here
                      std::cout << std::is_rvalue_reference_v<decltype(s.Get())> << '\n';

and

error: no matching member function for call to 'Get'
                      std::remove_reference_t<decltype(s.Get())>> << '\n';
                                                       ~~^~~
note: candidate template ignored: substitution failure [with self:auto = const S &]
     auto Get(this auto&& self) -> auto&& {

Plus other similar errors on next lines.

What's the issue?


Solution

  • This is a bug in clang in the std::forward_like implementation:
    clang 16 -> 17 regression: "deduced return type cannot be used before it is defined"

    The workaround is to use -fno-builtin-std-forward_like when compiling.
    godbolt example

    Or use clang trunk, which already contains the fix:
    godbolt example