После того, как я нашел ответы на многие свои вопросы о stackoverflow, я столкнулся с вопросом, на который я не могу найти ответа, и я надеюсь, что кто-то захочет мне помочь!
Моя проблема в том, что я хочу сделать явную шаблонизацию функции внутри класса на C ++. Мой компилятор (g ++) и взгляд на стандарт C ++ (§14.7.3) говорят мне, что эта специализация должна выполняться в пространстве имен, в котором объявлен класс. Я понимаю, что это означает, что я не могу поместить специализацию внутри класса, но я не вижу смысла в этом ограничении! Кто-нибудь знает, есть ли веская причина не позволять делать специализации внутри класса?
Я знаю, что есть обходные пути, например чтобы поместить функцию в структуру, но я хочу понять, почему язык имеет такой дизайн. Если есть веская причина не разрешать использование специализированных функций внутри класса, я думаю, мне следует знать об этом, прежде чем пытаться ее обойти.
Заранее спасибо!
Чтобы уточнить мой вопрос: вот код из тестового примера, который показывает, что я хочу сделать:
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {
privateVariable = 5;
};
virtual ~SpecializationTest() {};
void execute() {
execute<DIMENSIONALITY>();
};
private:
int privateVariable;
template <size_t currentDim>
static void execute() {
printf("This is the general case. Current dim is %d. The private variable is %d.\n", currentDim, privateVariable);
execute<currentDim-1>();
}
template <>
static void execute<0>() {
printf("This is the base case. Current dim is 0.\n");
}
};
Это невозможно; g ++ говорит:
SpecializationTest_fcn.h:27: error: explicit specialization in non-namespace scope ‘class MalinTester::SpecializationTest<DIMENSIONALITY>’
SpecializationTest_fcn.h:28: error: template-id ‘execute<0>’ in declaration of primary template
Если я помещу функцию execute вне класса в пространство имен MalinTester, это будет выглядеть так:
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY> class SpecializationTest {};
template <size_t currentDim>
void execute() {
printf("This is the general case. Current dim is %d. The private variable is %d.\n", currentDim, privateVariable);
execute<currentDim-1>();
}
template <>
void execute<0>() {
printf("This is the base case. Current dim is 0.\n");
}
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {};
virtual ~SpecializationTest() {};
void execute() {
MalinTester::execute<DIMENSIONALITY>();
};
private:
int privateVariable = 5;
};
};
};
и я не могу использовать частную переменную в шаблонных версиях выполнения, поскольку она является частной в классе. Я действительно хочу конфиденциальность, так как хочу, чтобы мои данные были максимально инкапсулированы.
Конечно, я могу отправить privateVariable в качестве аргумента функции, но я думаю, что было бы лучше избежать этого, и мне действительно интересно, есть ли у стандарта C ++ веская причина не разрешать явную специализацию, как в первом пример кода выше.
@Arne Mertz: Это обходной путь, который я пробовал, но он также не позволяет использовать privateVariable. И больше всего мне интересно, стоит ли это делать. Поскольку мне не разрешено делать специализацию функций-членов, возможно, мне также не следует делать специализации функций, инкапсулированных в структуры внутри класса.
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {
privateVariable = 5;
};
virtual ~SpecializationTest() {};
void execute() {
Loop<DIMENSIONALITY, 0>::execute();
};
private:
int privateVariable;
template <size_t currentDim, size_t DUMMY>
struct Loop {
static void execute() {
printf("This is the general case. Current dim is %d.\n", currentDim);
Loop<currentDim-1, 0>::execute();
}
};
template <size_t DUMMY>
struct Loop<0, DUMMY> {
static void execute() {
printf("This is the base case. Current dim is 0.\n");
}
};
};
};
template<size_t D> template<> void SpecializationTest<D>::execute<0>();
это запрещено) [temp.expl.spec] / 16. - person dyp   schedule 02.09.2013export
и связанным с ним поведением: в течение многих лет ни один крупный компилятор не реализовал его, до такой степени, что комитет проголосовал за его исключение, когда проголосовал за стандарт С ++ 11. Хотя я не знаю наверняка, применимо ли здесь то же самое обоснование, я думаю, что, по крайней мере, справедливо учитывать сложность реализации при голосовании за новую функцию. - person brunocodutra   schedule 04.09.2013