Явное объявление значения функции-члена в шаблоне C / как избежать проблемы с макросами

#c #templates #c-preprocessor #template-specialization

#c #шаблоны #c-препроцессор #шаблон-специализация

Вопрос:

Я думал, что это будет проще; У меня есть класс такого рода:

 template <int dim, int spacedim>
class FE_problem
{
    //...
   void generate_mesh();
}
  

У меня есть конкретный запрос для этой одной функции-члена, generate_mesh :
Мне нужно, чтобы оно явно отличалось в зависимости от значения dim и spacedim .

Я предпринял несколько попыток, таких как:

 template <int dim, int spacedim>
void FE_problem<1, 3>::generate_mesh()
{
...do a kind of mesh initialization ...
}

template <int dim, int spacedim>
void FE_problem<3, 3>::generate_mesh()
{
...do another kind of mesh initialization ...
}
  

Но не смог заставить его скомпилироваться.

Я пытался использовать std::enable_if , но я все еще недостаточно хорошо понимаю, как это работает, и я не знаю, правильный ли это способ.

Чтобы избежать (на данный момент) проблемы, которую я пробовал с макросами, используя следующий код при определении метода:

 #if DIM 1
template <int dim, int spacedim>
void FE_problem<dim,spacedim>::generate_mesh()
{
...do a kind of mesh initialization ...
}
#elif DIM 3
template <int dim, int spacedim>
void FE_problem<dim,spacedim>::generate_mesh()
{
...do another kind of mesh initialization ...
}
#endif
  

И затем, при инициализации класса в main функции, я попробовал что-то вроде:

 #define DIM 1
auto FE1 = FE_problem<1, 3>();
#undef DIM

#define DIM 3
auto FE2 = FE_problem<1, 3>();
#undef DIM
  

В надежде, что препроцессор выполнит правильные замены, но в результате результаты DIM не определены (в обоих случаях). Это из-за порядка, в котором препроцессор заменяет DIM? Есть ли исправление для этого?

Комментарии:

1. Посмотрите template specialization . В нем должно быть указано, что вам нужно сделать. По сути (если я правильно читаю) вы хотите создать специальные версии шаблонного кода для конкретных случаев.

Ответ №1:

У вас почти получилось. Когда вы специализируете шаблон, и это не частичная специализация, вы не включаете никаких параметров шаблона. Выполнение этого сделало бы код похожим

 template <int dim, int spacedim>
class FE_problem
{
public:
   void generate_mesh();
};

template <> // full specialization, leave template parameter blank as they are provided below
void FE_problem<1, 3>::generate_mesh()
//              ^^^^ specify the specialized types/values here  
{
    std::cout << "void FE_problem<1, 3>::generate_mesh()n";
}

template <> // full specialization, leave template parameter blank as they are provided below
void FE_problem<3, 3>::generate_mesh()
//              ^^^^ specify the specialized types/values here  
{
    std::cout << "void FE_problem<3, 3>::generate_mesh()n";
}

int main()
{
    FE_problem<1, 3>{}.generate_mesh();
    FE_problem<3, 3>{}.generate_mesh();
}
  

Который выводит

 void FE_problem<1, 3>::generate_mesh()
void FE_problem<3, 3>::generate_mesh()