Home > Blockchain >  conditional type define in c ?
conditional type define in c ?

Time:04-06

I need to define a template class A, which has a nested type according to nested type in template argument. Like this:

template<typename Container>
class A
{
public:
    using NestedType = if (Container has nested type Container::NestedTypeA)
    {
        Container::NestedTypeA;
    }
    else if (Container has nested type Container::NestedTypeB)
    {
        Container::NestedTypeB;
    }
    else
    {
        Container::NestedTypeC;
    }
};

How to implement this using declaration? Or is there another way to acheive the same effect?

CodePudding user response:

In C 20, you can just use concepts

template<typename Container>
struct B { };

template<typename Container>
  requires requires { typename Container::NestedTypeA; } 
struct B<Container> {
  using NestedType = typename Container::NestedTypeA;
};

template<typename Container>
  requires requires { typename Container::NestedTypeB; } &&
         (!requires { typename Container::NestedTypeA; })
struct B<Container> {
  using NestedType = typename Container::NestedTypeB;
};

template<typename Container>
  requires requires { typename Container::NestedTypeC; } &&
         (!requires { typename Container::NestedTypeA; }) &&
         (!requires { typename Container::NestedTypeB; })
struct B<Container> {
  using NestedType = typename Container::NestedTypeC;
};

template<typename Container>
class A : public B<Container> {};

Demo

CodePudding user response:

With std::conditional_t and appropriate traits, you might do something like:

template <typename Container>
struct NestedTypeA
{
    using type = typename Container::NestedTypeA;
};

template <typename Container>
struct NestedTypeB
{
    using type = typename Container::NestedTypeB;
};

template <typename Container>
struct NestedTypeC
{
    using type = typename Container::NestedTypeC;
};

template <typename T>
constexpr bool hasNestedTypeA = requires{ typename T::NestedTypeA; };

template <typename T>
constexpr bool hasNestedTypeB = requires{ typename T::NestedTypeB; };

template<typename Container>
class A
{
public:
    using NestedType = typename std::conditional_t<
                            hasNestedTypeA<Container>,
                            NestedTypeA<Container>,
                            std::conditional_t<hasNestedTypeB<Container>,
                                               NestedTypeB<Container>,
                                               NestedTypeC<Container>>
                        >::type;
};

Demo

  • Related