When inheriting member functions of C class, how to use type_traits to prevent them from being used under certain conditions?
I want to get Error Message, when Class B call function of foo()! when i using category random_access_iterator_tag, i can use function ( foo() )
#include <iostream>
#include <type_traits>
#include <iterator>
#include <ranges>
template<typename Derived> class Base
{
public:
void foo() {}
void goo() {}
};
class A : public Base<A>
{
public:
using category = std::random_access_iterator_tag;
};
class B : public Base<B>
{
public:
using category = std::bidirectional_iterator_tag;
};
int main()
{
A a;
B b;
a.foo(); // OK
a.goo(); // OK
b.foo(); // I want to get Error ( Compile )
b.goo(); // OK
}
CodePudding user response:
Mark foo
in the base protected
and then make it publicly available in the derived classes that should allow it to be used via using
declaration:
template<typename Derived> class Base
{
protected:
void foo() {}
public:
void goo() {}
};
class A : public Base<A>
{
public:
using category = std::random_access_iterator_tag;
using Base::foo;
};
//...
CodePudding user response:
Within CRTP, Derived class is incomplete, so you cannot check for category
.
If you create category traits outside, you might do:
template <typename T>
struct category;
template <typename T>
using category_t = typename category<T>::type;
template<typename Derived> class Base
{
public:
void foo()
requires(!std::is_same_v<category_t<Derived>, std::bidirectional_iterator_tag>)
// Or more appropriate condition
{}
void goo() {}
};
template <>
struct category<class A>
{
using type = std::random_access_iterator_tag;
};
class A : public Base<A> {};
template <>
struct category<class B>
{
using type = std::bidirectional_iterator_tag;
};
class B : public Base<B> {};
int main()
{
A a;
B b;
a.foo(); // OK
a.goo(); // OK
b.foo(); // KO as expected
b.goo(); // OK
}