简体   繁体   English

C++17中的部分class模板参数推导

[英]Partial class template argument deduction in C++17

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> :在下面的示例中,我们使用 C++17 功能“类模板参数推导”来推断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);
}

Now, is it possible to partially specify the template arguments, and let the remaining ones be deduced?现在,是否可以部分指定模板 arguments,并推导出其余的? 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 eg我试过了,例如

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 .但它不编译: '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?如果不能直接使用,有什么好的解决方法吗?

CTAD (Class Template Argument Deduction) is an all or nothing process currently. CTAD(类模板参数演绎)目前是一个全有或全无的过程。 You either specify nothing and allow the compiler to deduce all of the arguments, or you specify all of the arguments taking the compiler out of the loop. 您可以指定任何内容并允许编译器推导出所有参数,也可以指定使编译器退出循环的所有参数。

There is a paper ( P1021R0 ) which asks for this and more, but it has not yet been accepted. 有一篇论文( P1021R0 )要求更多,但尚未被接受。 There was a paper asking for partial specialization but after revisions it has been removed. 有一篇文章要求部分专业化,但在修订后它已被删除。 The newest revision still includes a proposal to have CTAD function when using an alias. 最新版本仍包含使用别名时具有CTAD功能的提议。


Per @ Barry Support for Alias templates ( P1814 ) and Aggregates ( P1816 ) have been added to the working draft for C++20. Per @ Barry支持别名模板( P1814 )和聚合( P1816 )已添加到C ++ 20的工作草案中。 No support for partial CTAD or CTAD with inherited constructors has been added. 不添加对具有继承构造函数的部分CTAD或CTAD的支持。

You might add deduction guide as follow: 您可以添加演绎指南如下:

template<class T, class U, class V>
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_ 如果要指定“默认”模板,可以使用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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM