0

I've read posts on this topic. But I still having problem when I try to do this.

template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };

#define TEST_TYPE2(who) typename animal < argument_type<T(who)>::type >

template<typename T, typename T2>
struct Pig 
{
    typedef TEST_TYPE2(int) type;
};

I'll get compile error

warning C4346: 'argument_type<T(int)>::type' : dependent name is not a type
prefix with 'typename' to indicate a type
see reference to class template instantiation 'Pig<T,T2>' being compiled
error C2923: 'animal' : 'argument_type<T(int)>::type' is not a valid template type argument for parameter 'T'

However, if I change

#define TEST_TYPE2(who) typename animal < argument_type<T(who)>::type >

to below

#define TEST_TYPE2(who) typename argument_type<T(who)>::type

It compiles fine. It seems that the compiler is unable to recognize the "::type" after i put it inside the <> brackets.

What can I do to make it work?

Community
  • 1
  • 1
HBZ
  • 499
  • 4
  • 11
  • Use "/E" to produce preprocessed output so you can see what your macros are being replaced by... then keep modifying the macros until you get the code you want. If that's too confusing, get the code right without macros first, so you have a target to work towards. – Tony Delroy Apr 10 '15 at 04:10
  • I clarified my question a little bit. And I also did try the code without marco and they do work. It only fails when i put them in marco. – HBZ Apr 10 '15 at 04:13
  • Anyway, in C++11, you may instead do `template using test_type2 = animal::type>;` and then in `Pig`: `using type = test_type2;` – Jarod42 Apr 10 '15 at 07:28

2 Answers2

2

The need to use typename is expected but try it this way.

#define TEST_TYPE2(who) animal < typename argument_type<T(who)>::type >
James Adkison
  • 9,412
  • 2
  • 29
  • 43
2

I think you've just got your typename in the wrong place; it has to precede the argument_type<T(who)>::type piece, not the animal<...> piece:

template<typename T> struct animal {};

template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };

#define TEST_TYPE2(who) animal<typename argument_type<T(who)>::type>

template<typename T, typename T2> struct Pig {
    typedef TEST_TYPE2(int) type;
};

int main(void) {
    return 0;
} // end main()

The above compiles fine for me.

bgoldst
  • 34,190
  • 6
  • 38
  • 64