Директива препроцессора #if и нетипичные параметры шаблона - PullRequest
3 голосов
/ 13 февраля 2012

Связанный:

Могу ли я сделать это?

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

Ответы [ 2 ]

7 голосов
/ 13 февраля 2012

Этот точный код не будет работать, потому что подстановка макросов происходит до создания экземпляра шаблона. Другими словами, к тому моменту, когда компилятор фактически начнет создавать экземпляр шаблона с аргументом N, препроцессор уже сделал свое условное включение. Более того, препроцессор не имеет семантического представления о том, что такое шаблон или что N является аргументом шаблона - он просто рассматривает N как токен препроцессора.

Если вы хотите получить этот эффект, вы можете использовать специализацию шаблона:

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

Надеюсь, это поможет!

6 голосов
/ 13 февраля 2012

Нет.Пропроцессор запускается до оценки шаблонов.Вместо этого используйте шаблонную специализацию.

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

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

// etc
...