跨多个参数的统一模板推导

Uniform template deduction across multiple arguments

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

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<double>(1.0, 1).

,尽管稍微冗长一点

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

此外,foo(1, 1.0) 会失败,因为第一个参数将 foo 设置为 foo<int>,因此第二个参数无法向下转换为 int。

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

只要在函数参数中使用模版参数先入"non-deducible contexts":

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<double>(1.0, 1) 的含义相同,并且函数特化具有参数 (double, double) 因此 1int 隐式转换为 double。反之,foo(1, 1.0) 表示 foo<int>(1, 1.0) 并且 1.0 隐式转换为 int.

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