带有隐式转换的模板函数参数推导

rus*_*tyx 3 c++ templates c++11 template-argument-deduction

我知道模板函数参数推导不考虑隐式转换。

所以这段代码不能编译:

#include <iostream>

template<class T>
struct A {};
struct B : public A<int> {};
struct C {
  operator B() { return {}; }
};

template<class X>
void test(A<X> arg1, A<X> arg2) {
  std::cout << "ok1";
}

int main() {
  B b;
  C c;
  test(b, c);  // error: no matching function for call to 'test'
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是如何通过身份typedef添加额外的间接级别使其工作:

#include <iostream>

template<class T>
struct A {};
struct B : public A<int> {};
struct C {
  operator B() { return {}; }
};

template<typename U> struct magic { typedef U type; };

template<class T> using magic_t = typename magic<T>::type;

template<class X>
void test(A<X> arg1, A<X> arg2) {
  std::cout << "ok1";
}

template<class X>
void test(A<X> arg3, magic_t<A<X>> arg4) {
  std::cout << "ok2";
}

int main() {
  B b;
  C c;
  test(b, c);  // prints "ok2"
}
Run Code Online (Sandbox Code Playgroud)

Godbolt 上的现场演示

magic_t<A<X>>最终如何匹配C

Igo*_*nik 6

第二个参数成为非推导上下文,不参与模板参数推导。X然后成功地从第一个参数推导出来。

  • @Incomputable 一个隐式转换序列不能有多个 *user-defined* 转换。它可能涉及多个标准转换。Derived-to-base 是一种标准转换。 (3认同)