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

时间:2019-08-19 20:33:27

标签: c++ c++17 template-argument-deduction class-template

在下面的示例中,我们使用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);
}

现在,是否可以部分指定模板参数,然后推导出其余参数?有效地类似于 这样:

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);
}

但无法编译:{{1​​}}。

以某种方式可以部分扣除吗?如果不可能直接解决,有什么好的解决方法?

2 个答案:

答案 0 :(得分:5)

CTAD(类模板参数推导)当前是一个全有或全无过程。您可以不指定任何内容并允许编译器演绎所有参数,或者指定所有参数使编译器退出循环。

有一篇论文(P1021R0)要求更多,但尚未被接受。有一篇论文要求部分专业化,但经过修订后删除。 The newest revision仍建议使用别名时具有CTAD功能。


每个@ {Barry已将对Alias模板(P1814)和聚合(P1816)的支持添加到C ++ 20的工作草案中。没有添加对部分CTAD或具有继承的构造函数的CTAD的支持。

答案 1 :(得分:3)

您可以添加以下扣除指南:

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>

如果要指定“默认”模板,则可以对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>