Следующий код представляет собой упрощенную минимальную версию функции, которую я пытаюсь реализовать для требований клиента.
Он не может скомпилироваться на компиляторе IBM XLC (версии 9 и 11, обе) с ошибкой A non-type template parameter cannot have type "int X::*".
, Тем не менее, я попробовал тот же код с g ++ 4.7.2, clang ++ 3.2 и Intel-13.0, и они успешно скомпилировали его.
Мне любопытно узнать, является ли XLC единственным здравым голосом здесь, или другие компиляторы верны?
struct X {
X() : y(123) {}
int y;
};
struct XFoo {
typedef int X::* Type;
};
template <typename Name, typename Name::Type value>
struct Bar {
typename Name::Type getValue(Name) {
return value;
}
};
template class Bar<XFoo, &X::y>; // xlc error here, works fine on others
int main() {}
Я прочитал стандартную главу C ++ 2003 о шаблонах несколько раз, и не смог окончательно найти то, что запрещает использовать <type> <class>::*
как не шаблонный тип. Я уже искал объяснения в SO и поисковых системах, но не нашел ни одного авторитетного источника, который бы помог мне решить.
Я понимаю, что это не может быть хорошей практикой кодирования, но это требуется для клиентского кода, поскольку их требования несколько уникальны. Я также попробовал различные другие альтернативы, но у них это не работает.
§ 14.1 / 4 стандарта C ++ 03 позволяет указатели на член в качестве параметра шаблона:
не типа Параметр шаблона должен иметь один из следующих (необязательно квалифицированных cv) типов:
- интеграл или тип перечисления,
- указатель на объект или указатель на функцию,
- ссылка на объект или ссылка на функцию,
- указатель на член.
Соответственно, согласно § 14.3.2 / 1:
Шаблон-аргумент для не типа, шаблонный параметр-шаблон должен быть один из:
- интегральная константа-выражение целочисленного или перечислимого типа; или же
- имя нетипового шаблона-параметра; или же
- адрес объекта или функции с внешней связью, включая шаблоны функций и идентификаторы шаблонов функций, но исключая нестатические члены класса, выражается как & id-выражение, где & необязательно, если имя ссылается на функцию или массив, или если соответствующий параметр шаблона является ссылкой; или же
- указатель на член, выраженный как описано в 5.3.1.
Таким образом, нетиповые параметры шаблона Можно быть указателями на участника. Существуют некоторые ограничения, которые применяются к специализации шаблонов, но в данном случае они не применяются.
Параметры шаблона указателя на член явно разрешены, XLC должен быть предоставлен отчет об ошибке.