У меня есть класс свойств, который связывает типы с целочисленными значениями.
struct traits
{
private:
template<int ID> struct type_impl {};
template<> struct type_impl<1> { using type = int; };
// ...
public:
template<int ID> using type = typename type_impl<ID>::type;
};
Я пишу шаблонную функцию, тип возвращаемого значения которой предоставляется указанным выше классом признаков, и специализирую его на различных значениях int:
template<int ID> traits::type<ID> function();
template<> inline traits::type<1> function<1>() { return 42; };
// ...
Это прекрасно компилируется с VS2015 (см. https://godbolt.org/z/LpZnni), но не с VS2017, который жалуется, что:
ошибка C2912: явная специализация 'int function‹1>(void)' не является специализацией шаблона функции
К моему удивлению, объявление функции, не являющейся шаблоном, как показано ниже, компилируется:
traits::type<1> other_function();
Открытие traits::type_impl
решает проблему компиляции, но я не понимаю, почему. Для меня либо специализация, и объявление other_function
должны компилироваться с traits::type_impl
private или без.
Спасибо за помощь.
Дальнейшее расследование после комментария @rubenvb Я понимаю, что опубликованный мной код является незаконным, поэтому вместо этого я попытался сделать частичную специализацию (что я считаю законным):
struct traits
{
private:
template<int ID,bool=true> struct type_impl {};
template<bool B> struct type_impl<1,B> { using type = int; };
// ...
public:
template<int ID> using type = typename type_impl<ID>::type;
};
template<int ID> traits::type<ID> function();
template<> inline traits::type<1> function<1>() { return 42; };
Теперь все компиляторы довольны, но VS2017 все еще хочет traits::type_impl
public. Я предполагаю, что это ошибка Visual Studio.