Reputation: 2147
I work with containers.
If A
is a container then container_traits<A>::reference_container
must type an A
.
If container RefContainer<C>
is_base_of A
, then container_traits<A>::reference_container
must type a C
.
The following code does this upcasting (or dereferencing, as I say).
The problem is that, even if reference = false
compiler checks if C::reference_container
exists as type, and fail to compile.
Any other approaches?
#include <iostream>
using namespace std;
template<typename C> struct RefContainer;
template<class C>
class container_traits
{
template <typename R>
static std::true_type ref_helper(const RefContainer<R>&);
static std::false_type ref_helper(...);
public:
constexpr static bool reference = decltype(ref_helper(std::declval<C>()))::value;
typedef typename std::conditional<reference, typename C::reference_container, C>::type reference_container;
};
template<typename C>
struct RefContainer : public C { typedef typename container_traits<C>::reference_container reference_container; };
struct Container1 {};
struct Container2 {};
template<typename C> struct D : public RefContainer<C> {};
struct E : public RefContainer<D<RefContainer<Container1>>> {};
int main()
{
container_traits<Container1>::reference_container e; // It is Container1
container_traits<RefContainer<Container1>>::reference_container f; // dereference to Container1
container_traits<D<Container2>>::reference_container // dereference to Container2
container_traits<E>::reference_container h; // dereference to Container1
return 0;
}
Upvotes: 0
Views: 156
Reputation: 4194
Just create helper class
template<class T, bool der>
struct hlp
{
typedef T type;
}
template<class T>
struct hlp<RefContainer<T>, true>
{
typedef T::reference_container type;
}
Upvotes: 1