Можно ли определить во время компиляции точную базу шаблона класса в зависимости от его параметров? Например, у меня есть шаблон класса, который принимает один аргумент в своем конструкторе, и я хочу расширить этот класс другим аргументом, для которого будет использоваться другой конструктор. Проблема заключается в том, что этот второй экземпляр (с двумя аргументами) должен иметь другой базовый класс, чем класс с одним параметром. Я могу определить правильный базовый класс с помощью std::conditional
, но проблема заключается в наличии обоих конструкторов в одном шаблоне класса. Например:
#include <type_traits>
struct X
{
};
struct Y
{
};
struct XX
{
};
struct XY
{
};
template<class T, class V = void>
struct Z: public std::conditional_t<std::is_void_v<V>, XX, XY>
{
Z(T&& t, V&& v)
: XY()
{
// do smth with t and v
}
Z(T&& t)
: XX()
{
// do smth with t
}
};
int main()
{
auto a = Z(X(), Y());
auto b = Z(X()); // <-- this instantiation fails
}
Здесь Z(X(), Y())
работает, но для Z(X())
происходит сбой с ошибкой компиляции:
main.cpp: In instantiation of 'struct Z<X, void>':
main.cpp:39:19: required from here
main.cpp:23:5: error: forming reference to void
23 | Z(T&& t, V&& v)
| ^
Обновление:
Пытался сделать шаблон с двумя аргументами enable_if
, но он не работает (такой же forming reference to void
, как в исходном коде):
template<class = std::enable_if<! std::is_void_v<V>>>
Z(T&& t, V&& v)
: XY()
{
// do smth with t and v
}