bobobobo
bobobobo

Reputation: 67306

Preprocessor directive #if and non-type template parameters

Related:

Can I do this?

template <int N> union Vector
{
  float e[ N ] ;
  // If N is 3, define x,y,z components
  #if N==3
  struct { float x,y,z ; } ;
  #elif N==2
  struct { float x,y ; } ;
  #endif
} ;

// use
int main()
{
  Vector<2> xy ;
  xy.e[ 0 ] = 5 ;
  xy.e[ 1 ] = 2 ;
  xy.x = 2 ;

  Vector<3> xyz ;
  xyz.z = 4 ;
}

Upvotes: 3

Views: 1047

Answers (2)

user1203803
user1203803

Reputation:

No. The proprocessor is run before the templates are evaluated. Use template specialization instead.

template<int N> union Vector {
  float e[N];
};

template<> union Vector<3> {
  float e[3];
  struct { float x, y, z; };
};

// etc

Upvotes: 6

templatetypedef
templatetypedef

Reputation: 373112

This exact code won't work, because macro substitution occurs before template instantiation occurs. In other words, by the time that the compiler is actually going to start instantiating the template with the argument N, the preprocessor has already done its conditional inclusion. Moreover, the preprocessor has no semantic idea of what a template is or that N is the template argument - it just treats N as a preprocessor token.

If you want to get this effect, you can use template specialization:

template <int N> union Vector
{
  float e[ N ] ;
};

template <> union Vector<3>
  float e[ 3 ] ;
  float x, y, z;
} ;

template <> union Vector<2>
  float e[ 2 ] ;
  float x, y;
} ;

Hope this helps!

Upvotes: 8

Related Questions