#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()