Цель состоит в том, чтобы создать своего рода «умный получатель», который получает значение из текущего объекта, если он присутствует, если нет, он ищет значение в родительском объекте.
Таким образом, этот класс ValueGetter содержит указатель на объект, в котором он содержится (получает его как параметр времени выполнения в конструкторе), и указатель на член, с которым он работает как параметр шаблона.
Это самый простой пример:
template <class StyleType, int StyleType::*value>
struct ValueGetter
{
ValueGetter(StyleType* containedIn);
int get();
// Looks if the value is present in this style,
// if not it looks for the value in the parent style
};
struct Style
{
Style *parent;
int a;
ValueGetter<Style, &Style::a> x; // Error: 'Style::a' : is not a type name, static, or enumerator
};
Когда я перемещаю x вне области видимости класса, он компилируется.
Как правило, класс может содержать шаблон, зависящий от типа класса, так почему же это не работает?
Есть ли другой способ решить эту проблему, не сохраняя указатель на член во время выполнения в конструкторе? (Таким образом, структура будет содержать дополнительный указатель для каждого значения)
Изменить: Я только что успешно скомпилировал его в GCC, но не в MSVC (2012), так это ошибка компилятора MSVC?
Я не думаю, что указатели (не путать с типами указателей, как в T *) разрешены в качестве параметров шаблона в 03 C ++, только имена типов, целочисленные константы или константы перечисления. Даже не с плавающей запятой / двойные константы. Это включает в себя указатели членов класса.
Обновить:
Также работают статические нетиповые параметры:
template <class StyleType, int *value>
struct ValueGetter
{
ValueGetter(StyleType* containedIn);
int get();
// Looks if the value is present in this style,
// if not it looks for the value in the parent style
};
struct Style
{
Style *parent;
static int a;
ValueGetter<Style, &Style::a> x; // Error: 'Style::a' : is not a type name, static, or enumerator
};
Других решений пока нет …