Явные специализации в области видимости класса - это функция C ++ 17 ( CWG 727 не была DR по сравнению с C ++ 14, это было новым для C ++ 17), которую g cc просто не делает еще не реализовано (это g cc ошибка 85282 ).
Здесь есть еще одна особенность C ++ 17 - расширение того, какие аргументы можно использовать в качестве нетиповых параметров шаблона ( N4198 для пояснения, N4268 для формулировки). В C ++ 14 vecForIndex<VecIndex::first>::vecPtr
не был допустимым нетиповым аргументом шаблона, потому что только допустимые аргументы для указателей на члены (как в вашем примере) были:
- Точно выражения вида
&T::X
(например, буквально тот синтаксис) - Произвольное константное выражение, которое оценивается как нулевое значение указателя.
И это все. vecForIndex<VecIndex::first>::vecPtr
не относится ни к одной из этих вещей, поэтому он плохо сформирован в C ++ 14. В C ++ 17 ограничения на нетипичные параметры шаблонов намного слабее, так что это просто работает.
Если вы хотите, чтобы все это оставалось в теле класса, вы можете использовать шаблон функции с if constexpr
вместо специализированного шаблона класса. Это тоже меньше кода:
template <VecIndex I>
constexpr auto vecForIndex()
{
if constexpr (I == VecIndex::first) return &Vecs::vec1;
else if constexpr (I == VecIndex::second) return &Vecs::vec2;
}
, а затем:
static void workSpecificVec() {
work<vecForIndex<VecIndex::first>()>();
}