Для полноты, вот уродливый способ.
Как упоминалось в комментариях, TestFunc
является функцией-членом, а не типом, поэтому, если вы хотите ссылаться на явную специализацию, вы необходимо использовать указатель на функцию-член . В нашем случае это будут указатели следующего типа.
using MemberTestFunction = void (MyClass::*)();
Затем мы можем получить указатели на true
и false
специализации TestFunc
следующим образом:
template <typename T>
class MyClass
{
// ...
constexpr static MemberTestFunction TestTrue = &MyClass::TestFunc<true>;
constexpr static MemberTestFunction TestFalse = &MyClass::TestFunc<false>;
};
Если вы не знакомы с указателями на функции-члены, синтаксис для вызова TestTrue
и TestFalse
может выглядеть довольно странно. Если вы находитесь внутри функции-члена, вы можете вызывать эти функции либо с помощью оператора ->*
, либо с помощью std::invoke
(C ++ 17) из <functional>
:
template <typename T>
class MyClass
{
// ...
void foo() {
// Direct call with pointer.
(this->*TestTrue)();
// Call using std::invoke.
std::invoke(TestTrue, this);
}
};
В качестве альтернативы, за пределами MyClass
, эти вызовы могли бы выглядеть следующим образом:
MyClass<nullptr_t> x;
// Using type deducation.
(x.*decltype(x)::TestTrue)();
// Using fully qualified name.
(x.*MyClass<nullptr_t>::TestTrue)();
// Using std::invoke (with type deducation).
std::invoke(decltype(x)::TestTrue, x);
Само собой разумеется, что это излишне непонятный способ выполнения любой простой задачи. Я бы не рекомендовал использовать эту технику для создания новых функций (как предлагал HolyBlackCat) или просто называть TestFunc<true>()
и TestFunc<false>()
явно на месте вызова.