0

Given the following classes:

// Some random class
class A { };

// A templated class with a using value in it.
template<class TYPE_B> 
class B {
  public:
    using TYPE = TYPE_B;
};

Next we use these two classes in class C. But if we are using B as the template parameter we would like to obtain the TYPE defined in it.

template<class TYPE_C>
class C {
    // A check to see if we have a class of type B 
    static constexpr bool IS_B = std::is_same<B<int32_t>, TYPE_C>::value ||
                                 std::is_same<B<int64_t>, TYPE_C>::value;

  public:
    // This is what not works. How to get B::TYPE here?
    using TYPE = std::conditional<IS_B, TYPE_C::TYPE, TYPE_C>;
};

Class C would we used like:

C<A> ca;
C<B<int32_t>> cb32;
C<B<int64_t>> cb64;

I am compiling this in GCC. My fear what I would like not have to do is to use the std::is_same statement for each type used with B. Put that in the std::conditional. Are there any alternatives?

Bart
  • 1,405
  • 6
  • 32
  • What is `DATA_TYPE`? You're most likely missing a `typename` keyword prior before `DATA_TYPE::TYPE`. – Holt Jan 11 '22 at 13:22
  • Sorry copy past fault. I will modify the code. – Bart Jan 11 '22 at 13:23
  • Then you do need `typename TYPE_C::TYPE`. The duplicate will tell you why. I don't know which compiler you're using but you should carefully read the error messages because gcc, clang and MSVC all tell you what to do in this case, see https://godbolt.org/z/YbbedzK61. – Holt Jan 11 '22 at 13:26
  • @holt will have to look more closely at the awnser but first results are not good. `using TYPE = std::conditional;` does not build. Will let you know what I find later. – Bart Jan 11 '22 at 13:30
  • I removed the duplicate, Your question is slightly different, you need to delay the `::TYPE` in a different template. There are most likely duplicate on SO for this. – Holt Jan 11 '22 at 13:35
  • Probably, I did look but did not find the proper search term to get it. It appears also that std::conditional does not work with using. – Bart Jan 11 '22 at 13:37

1 Answers1

0

You have two issues in your code:

  1. You are missing a typename before TYPE_C::TYPE. Since TYPE_C::TYPE is a dependent name, you need to use typename to tell the compiler that you are looking for a type.

  2. You cannot use TYPE_C::TYPE ins the std::conditional1 expression because when TYPE_C is not B<>, that expression is invalid, but will still be evaluated.

One simple solution is to use an intermediate template to access the type, using template specialization, e.g.

template <class T>
struct get_C_type {
    using type = T;
};

template <class T>
struct get_C_type<B<T>> {
    using type = T;
};

template<class TYPE_C>
class C {
public:
    // you still need a typename here
    using TYPE = typename get_C_type<TYPE_C>::type;
};

1 You probably want to use std::conditional_t or std::conditional<>::type here.

Holt
  • 36,600
  • 7
  • 92
  • 139