In the example below, we use the C++17 feature "Class template argument deduction" to deduce that val
is of type Base<int, double, bool>
:
template<class T, class U, class V>
struct Base {
Base(T, U) { };
Base(T, U, V) { };
Base(V) { };
};
void func() {
Base val(1, 4., false);
}
Now, is it possible to partially specify the template arguments, and let the remaining ones be deduced? Effectively something like this:
Base<V = bool> val1(1, 4.); // U & V deduced --> Base<int, double, bool>
Base<T = bool, T = int> val2(5.); // V deduced --> Base<bool, int, double>
I've tried e.g.
template<class T, class U> using Base2 = Base<T, U, double>;
void func() {
NewBase2 val(1, 2);
}
but it doesn't compile: 'Base2': use of alias template requires template argument list
.
Is partial deduction possible somehow? If it is not possible directly, are there any good workarounds?
You might add deduction guide as follow:
template<class T, class U>
Base(T, U) -> Base<T, U, bool>;
template<class V>
Base(V) -> Base<bool, int, V>;
which allows
Base val1(1, 4.); // Base<int, double, bool>
Base val2(5.); // Base<bool, int, double>
If you want to specify the "default" template, you might use the old way with make_
template <typename V, typename T, typename U>
Base<T, U, V> make_Base(T t, U u)
{
return Base<T, U, V>{t, u};
}
template <typename T, typename U, typename V>
Base<T, U, V> make_Base(V v)
{
return Base<T, U, V>{v};
}
auto val1 = make_Base<bool>(1, 4.); // Base<int, double, bool>
auto val2 = make_Base<bool, int>(5.); // Base<bool, int, double>