C++17 中的部分 class 模板参数推导
Partial class template argument deduction in C++17
在下面的示例中,我们使用 C++17 功能 "Class template argument deduction" 来推断 val
的类型为 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);
}
现在,是否可以部分指定模板参数,并让其余的推导?实际上像这样的东西:
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>
我试过了,例如
template<class T, class U> using Base2 = Base<T, U, double>;
void func() {
NewBase2 val(1, 2);
}
但无法编译:'Base2': use of alias template requires template argument list
.
是否可以通过某种方式进行部分扣除?如果直接不行,有什么好的解决方法吗?
CTAD(Class 模板参数推导)目前是一个全有或全无的过程。您要么不指定任何内容并允许编译器推导所有参数,要么指定所有参数使编译器退出循环。
有一篇论文(P1021R0) which asks for this and more, but it has not yet been accepted. There was a paper asking for partial specialization but after revisions it has been removed. The newest revision还包括提议在使用别名时具有CTAD功能
Per @Barry Support for Alias templates (P1814) and Aggregates (P1816) 已添加到 C++20 的工作草案中。未添加对部分 CTAD 或具有继承构造函数的 CTAD 的支持。
您可以添加推导指南如下:
template<class T, class U, class V>
Base(T, U) -> Base<T, U, bool>;
template<class V>
Base(V) -> Base<bool, int, V>;
允许
Base val1(1, 4.); // Base<int, double, bool>
Base val2(5.); // Base<bool, int, double>
如果您想指定 "default" 模板,您可以使用 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>
在下面的示例中,我们使用 C++17 功能 "Class template argument deduction" 来推断 val
的类型为 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);
}
现在,是否可以部分指定模板参数,并让其余的推导?实际上像这样的东西:
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>
我试过了,例如
template<class T, class U> using Base2 = Base<T, U, double>;
void func() {
NewBase2 val(1, 2);
}
但无法编译:'Base2': use of alias template requires template argument list
.
是否可以通过某种方式进行部分扣除?如果直接不行,有什么好的解决方法吗?
CTAD(Class 模板参数推导)目前是一个全有或全无的过程。您要么不指定任何内容并允许编译器推导所有参数,要么指定所有参数使编译器退出循环。
有一篇论文(P1021R0) which asks for this and more, but it has not yet been accepted. There was a paper asking for partial specialization but after revisions it has been removed. The newest revision还包括提议在使用别名时具有CTAD功能
Per @Barry Support for Alias templates (P1814) and Aggregates (P1816) 已添加到 C++20 的工作草案中。未添加对部分 CTAD 或具有继承构造函数的 CTAD 的支持。
您可以添加推导指南如下:
template<class T, class U, class V>
Base(T, U) -> Base<T, U, bool>;
template<class V>
Base(V) -> Base<bool, int, V>;
允许
Base val1(1, 4.); // Base<int, double, bool>
Base val2(5.); // Base<bool, int, double>
如果您想指定 "default" 模板,您可以使用 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>