Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add members to concept-specialized classes with non-inline definition

Look at this code.

#include <type_traits>

template<typename T>
struct C;

template<typename T>
    requires std::is_integral_v<T>
struct C<T>
{
    void f();
};

template<typename T>
    requires std::is_integral_v<T>
void C<T>::f()
{

}

template<typename T>
    requires std::is_pointer_v<T>
struct C<T>
{
    void f();
};

template<typename T>
    requires std::is_pointer_v<T>
void C<T>::f()
{

}

I want to add functions to the specializations as you see, i.e. functions that don't exist in the non-specialized variant. But the compiler says

class template "C<T>" has no member "f"'.

The above code compiles without any problems with GCC 11.1.0, but not with Clang 13 or current MSVC.

I want to forward-declared class C without any implementation. And I don't want to have a defined class C with a f inside it. The added f in the specializations would have no meaning in the base-class I'm concerned about.

like image 346
Bonita Montero Avatar asked Dec 10 '21 14:12

Bonita Montero


1 Answers

I believe what you've written is correct Standard C++20; the fact that it doesn't currently compile on Clang is a compiler bug in Clang (#56442, possibly also #56482).

The only ways I see to work around the bug are:

  • Use plain old-fashioned SFINAE instead of C++20 constraints (e.g. use enable_if_t)

  • Define the member function right at the point of declaration, instead of trying to define it out-of-line. (You're already putting it in the same header file, so what's the problem with just defining it in-line?)

like image 51
Quuxplusone Avatar answered Jan 16 '23 16:01

Quuxplusone