【问题标题】:Uniform template deduction across multiple arguments跨多个参数的统一模板推导
【发布时间】:2019-06-04 23:12:15
【问题描述】:

我想看看是否有可能(尽管我感觉不可能)是否有可能根据给定的第一个模板参数应用统一类型。例如:

template <class T>
void foo(T, T) {}

int main() {
  // deduced as int
  foo(1, 1);

  // deduced as double
  foo(1.0, 1.0);

  // not deducible, will error.
  //foo(1.0, 1);

  return 0;
}

是否有一些技术可以让我将 foo 的第二个参数强制为第一个?我确实意识到规范的解决方案是foo&lt;double&gt;(1.0, 1)

话虽如此,我希望能够执行foo(1.0, 1),这将强制将第二个参数类型作为第一个,并将 1 向上转换为 1.0。

此外,foo(1, 1.0) 会失败,因为第一个参数将 foo 设置为 foo&lt;int&gt;,因此第二个参数不能向下转换为 int。

最后,我希望能够在没有递归模板化的情况下做到这一点,因为我想将此技术应用于对象构造函数。

【问题讨论】:

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


    【解决方案1】:

    只需在函数参数中使用模板参数后先进入“不可演绎的上下文”:

    template <typename T>
    struct type_identity {
        using type = T;
    };
    template <typename T>
    using type_identity_t = typename type_identity<T>::type;
    
    template <class T>
    void foo(T, type_identity_t<T>) {}
    

    现在foo(1.0, 1)foo&lt;double&gt;(1.0, 1) 的含义相同,并且函数特化具有参数(double, double),因此1 隐式从int 转换为double。反之,foo(1, 1.0) 表示foo&lt;int&gt;(1, 1.0)1.0 隐式转换为int

    (注意std::type_identity_t is coming in C++20。)

    【讨论】:

    • 美丽。我很好奇是否有办法让foo(1, 1.0) 失败。事实上,当前的解决方案更好,因为它可以双向工作,但我仍然很好奇。
    • 失败基于什么? int 到 double 和 double 到 int 都是允许的标准转换,并且通常都是缩小转换。
    • 哦。抱歉,出于某种原因,我认为 double to int 需要明确的向下转换。
    猜你喜欢
    • 1970-01-01
    • 2018-07-04
    • 2020-05-25
    • 2013-06-30
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多