ADL failing to find friend function GCC 10.2.0

  argument-dependent-lookup, c++, gcc

I’m having issues with ADL not finding hidden friends. I’m working on a c++20 codebase that is made to run on the latest versions of msvc however I’m moving it back a bit and getting it to compile with gcc 10.2.0 on arch linux. There are a few isolated places that are complaining about these hidden friends being out of scope so it really seems like there is some compiler flag that I’m missing rather than an error in the code especially as it does compile on MSVC and from the c++ compatibility chart for gcc it doesn’t seem like its missing any required features.

I have added the following to the cmake to try and ensure that the GNU extensions are disabled and c++20 standard is enabled.

set_target_properties(ttauri PROPERTIES
    CXX_STANDARD 20
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS OFF
)

Here is an example of one of these functions.

    constexpr static ssize_t get_zero = -1;
    constexpr static ssize_t get_one = -2;

    template<ssize_t I>
    [[nodiscard]] friend constexpr T &get(numeric_array &rhs) noexcept
    {
        static_assert(I >= 0 && I < N, "Index out of bounds");
        return get<I>(rhs.v); // v is a different class so its not the numeric_array get function
    }

    template<ssize_t I>
    [[nodiscard]] friend constexpr T get(numeric_array &&rhs) noexcept
    {
        static_assert(I >= -2 && I < N, "Index out of bounds");
        if constexpr (I == get_zero) {
            return T{0};
        } else if constexpr (I == get_one) {
            return T{1};
        } else {
            return get<I>(rhs.v); // v is a different class so its not the numeric_array get function
        }
    }

    template<ssize_t I>
    [[nodiscard]] friend constexpr T get(numeric_array const &rhs) noexcept
    {
        static_assert(I >= -2 && I < N, "Index out of bounds");
        if constexpr (I == get_zero) {
            return T{0};
        } else if constexpr (I == get_one) {
            return T{1};
        } else {
            return get<I>(rhs.v); // v is a different class so its not the numeric_array get function
        }
    }

And here it is used later in the same class.

    template<ssize_t I, ssize_t FirstElement, ssize_t... RestElements>
    constexpr void swizzle_detail(numeric_array &r) const noexcept
    {
        static_assert(I < N);
        static_assert(FirstElement >= -2 && FirstElement < N, "Index out of bounds");

        get<I>(r) = get<FirstElement>(*this); // Error on this line
        if constexpr (sizeof...(RestElements) != 0) {
            swizzle_detail<I + 1, RestElements...>(r);
        }
    }

I think that what I’m asking is different to another post (Hidden friend template function not found by ADL)
in that my return type is a class template and not the function template.

Source: Windows Questions C++

LEAVE A COMMENT