【问题标题】:Partial class template argument deduction in C++17C++17中的部分类模板参数推导
【发布时间】:2019-12-25 01:52:17
【问题描述】:

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

但它无法编译:'Base2': use of alias template requires template argument list

是否可以通过某种方式进行部分扣除?如果不能直接使用,有什么好的解决方法吗?

【问题讨论】:

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


【解决方案1】:

CTAD(Class Template Argument Deduction)目前是一个全有或全无的过程。您要么不指定任何内容并允许编译器推导出所有参数,要么指定所有参数使编译器退出循环。

有一篇论文 (P1021R0) 要求这个和更多,但它尚未被接受。 有一篇论文要求部分专业化,但在修改后已被删除。 The newest revision 仍然包含在使用别名时具有 CTAD 功能的提议。


根据@Barry,对别名模板 (P1814) 和聚合 (P1816) 的支持已添加到 C++20 的工作草案中。不支持部分 CTAD 或带有继承构造函数的 CTAD。

【讨论】:

  • 论文的最新版本是P1021,它被分成了两个不同的论文:P1814 for alias templatesP1816 for aggregates。两者都已添加到 C++20 的工作草案中。不会有任何部分 CTAD,也不支持继承的构造函数。
  • @Barry 感谢您的消息来源。我会把它添加进去。
【解决方案2】:

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

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 2017-12-30
    • 2021-04-17
    • 1970-01-01
    相关资源
    最近更新 更多