I was doing some experiments with concepts, and I was trying to have constrained member functions that must be instantiated only if a concept is satisfied:
template <typename T>
concept Fooable = requires(T o)
{
o.foo(uint());
};
template <typename T>
concept Barable = requires(T o)
{
o.bar(uint());
};
class Foo
{
public:
using FooType = int;
void foo(uint) {}
};
class Bar
{
public:
using BarType = double;
void bar(uint) {}
};
template <typename T>
class C
{
public:
void fun(typename T::FooType t) requires Fooable<T> {}
void fun(typename T::BarType t) requires Barable<T> {}
};
int main()
{
C<Foo> f;
}
This piece of code does not compile both on GCC 11.2 and Clang 14, saying:
main.cpp: error: no type named 'BarType' in 'Foo'
main.cpp: error: no type named 'BarType' in 'Foo'
void fun(typename T::BarType t) requires Barable<T> {}
~~~~~~~~~~~~^~~~~~~
main.cpp: note: in instantiation of template class 'C<Foo>' requested here
C<Foo> f;
^
However, since I am declaring a C object with Foo type, I expect that the member function fun with BarType would not be instantiated.
Could this be both a GCC and Clang bug? Or am I doing something wrong? Is there any way to implement this using concepts?