У меня есть класс признаков, который связывает типы с целочисленными значениями.
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 или none.
Спасибо за вашу помощь.
Дальнейшее расследование после комментария @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
публичность.Я предполагаю, что это ошибка Visual Studio.