Если я добавляю функцию-член f
к производному классу, это скрывает весь набор перегрузки для f
базового класса
struct B2{
int f(int);
int f(float);
};
struct D: B2{
int f(std::string);
};
D b;
b.f(42); // fails to compile because int B2::f(int) is not available.
Стандартным исправлением для этого является объявление использования
struct D: B2 {
int f(std::string);
using B2::f;
};
В моем случае B является параметром шаблона:
template <typename B>
struct D: B {
int f(std::string);
using B::f;
};
с дополнительной сложностью, что B
может иметь или не иметь метод f
и отсутствие f
в базовом классе вызывает ошибки компилятора.
struct B1 {
};
template <typename B>
struct D: B {
int f(std::string);
using B::f;
};
void test() {
D<B1> b; // error: no members matching 'B1::f' in 'struct B1'
}
Шаблоны, подобные объявлениям псевдонимов, очевидно, не могут использоваться для объявлений using
:
#include <string>
#include <type_traits>
struct B1 {
};
template <typename B>
struct D: B {
int f(std::string);
template <typename = typename std::enable_if_t<std::is_same_v<B2, B>>>
using B::f;
};
void test() {
D<B1> b;
}
это приводит к
<source>:15:10: error: expected '=' before '::' token
using B::f;
^~
<source>:15:12: error: 'f' in namespace '::' does not name a type
using B::f;
Итак, мой вопрос: каков рекомендуемый способ отображения / исчезновения объявления using
на основе чего-то известного во время компиляции, которое не известно во время записи кода?(т.е. я думаю о чем-то с помощью sfinae / std :: enable_if / if constexpr).
PS:
Я думаю об использовании метода вариационных шаблонов f
в D
он перенаправляет на базовые классы f
в общем случае и специализирует одну опцию, которую я хотел бы добавить.Это может быть лучше, чем using
декларация?