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

Templates 跨多个参数的统一模板推导,templates,c++17,template-argument-deduction,Templates,C++17,Template Argument Deduction,我想看看是否有可能(尽管我感觉不可能)基于给出的第一个模板参数应用统一类型。例如: 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; } 模板 void foo

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

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;
}
模板
void foo(T,T){}
int main(){
//推断为int
foo(1,1);
//推断为双重的
foo(1.0,1.0);
//不可推断,会出错。
//foo(1.0,1);
返回0;
}
有没有什么技术可以让我强制foo的第二个参数正好是第一个?我确实意识到规范的解决方案,尽管稍微详细一点,应该是
foo(1.0,1)

也就是说,我希望能够执行
foo(1.0,1)
,这将强制第二个参数类型作为第一个,并将1向上转换为1.0

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


最后,我希望能够在不进行递归模板化的情况下实现这一点,因为我希望将此技术应用于对象构造函数。

只需在函数参数中使用模板参数,然后将其应用到“不可推断的上下文”:

模板
结构类型标识{
使用类型=T;
};
模板
使用type\u identity\u t=typename type\u identity::type;
模板
void foo(T,type_identity_T){}
现在
foo(1.0,1)
的意思与
foo(1.0,1)
相同,函数专门化具有参数
(double,double)
,因此
1
被隐式地从
int
转换为
double
。另一方面,
foo(1,1.0)
意味着
foo(1,1.0)
1.0
被隐式转换为
int


(注意。)

漂亮。不过我很好奇是否有办法让
foo(1,1.0)
失败。目前的解决方案实际上更好,因为它可以双向工作,但我仍然很好奇。失败基于什么?int-to-double和double-to-int都是允许的标准转换,并且通常都是窄化转换。doh。出于某种原因,我认为double to int需要一个显式的向下转换。
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>) {}