【问题标题】:Template function argument deduction with an implicit conversion带有隐式转换的模板函数参数推导
【发布时间】:2017-08-18 21:21:02
【问题描述】:

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

所以这段代码无法编译:

#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'
}

我不明白的是如何使用 identity 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"
}

Live demo on Godbolt

magic_t&lt;A&lt;X&gt;&gt; 最终如何匹配 C

【问题讨论】:

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


    【解决方案1】:

    第二个参数变成non-deduced context,不参与模板实参推导。然后从第一个参数成功推导出X

    【讨论】:

    • 如何允许编译器进行两次转换?还是派生到不计入基础转化?
    • @Incomputable 我不确定我是否理解这个问题。您指的是哪两种转化,从什么转化到其他转化?
    • 从 c 到 b,然后从 b 到 a。
    • @Incomputable 一个隐式转换序列不能有多个用户定义的转换。它可能涉及多个标准转换。 Derived-to-base 是一种标准转换。
    • @Incomputable 您可以在相应的standardese 中阅读有关 Igor 声明的更多信息。还有一个nice table in the standard 表示转化排名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2023-03-09
    相关资源
    最近更新 更多