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> {};
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;
};