c++ - 为什么编译器在下面的例子中没有选择我的函数模板重载?

标签 c++ templates overloading function-templates overload-resolution

给定以下函数模板:

#include <vector>
#include <utility>

struct Base { };
struct Derived : Base { };

// #1
template <typename T1, typename T2>
void f(const T1& a, const T2& b)
{
};

// #2
template <typename T1, typename T2>
void f(const std::vector<std::pair<T1, T2> >& v, Base* p)
{
};

为什么下面的代码总是调用重载#1 而不是重载#2?

int main()
{
    std::vector<std::pair<int, int> > v;
    Derived derived;

    f(100, 200);  // clearly calls overload #1
    f(v, &derived);         // always calls overload #1

    return 0;
}

鉴于 f 的第二个参数是 Base 的派生类型,我希望编译器会选择重载 #2,因为它比重载 #1 中的泛型。

是否有任何技术可以用来重写这些函数,以便用户可以编写 main 函数中显示的代码(即,利用参数类型的编译器推导)?

最佳答案

您可以这样做:

f(v, static_cast<Base*>(&derived));

或者使用 SFINAE 去除第一个函数作为选择候选:

// Install boost library and add these headers:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

// #1 - change it to look like this (note the keyword void changed positions)
template <typename T1, typename T2>
typename boost::disable_if<
   typename boost::is_convertible<T2, Base*>, void>::type
f(const T1& a, const T2& b)
{
};

// #2 - this one can stay the same
template <typename T1, typename T2>
void f(const std::vector<std::pair<T1, T2> >& v, Base* p)
{
};

关于c++ - 为什么编译器在下面的例子中没有选择我的函数模板重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1567834/

相关文章:

C++:除了虚函数之外,[类名 "undefined reference to '的]' "类型信息的原因是什么

c++ - 如何使用参数包参数 typedef 函数指针类型

c++ - 如何在编译时专门化大型模板函数中的一小部分

c++ - 普通函数和模板函数之间的优先级

c++ - cv::detail::MultiBandBlender 照片末尾出现奇怪的白色条纹

c++ - QTimer 不正确的计时

c++ - 为什么 printf 在打印十六进制时不只打印一个字节?

c++ - 如何在C++中确定嵌套类结构的外部类

c# - 方法重载解析如何工作(LINQ Where 扩展方法)?

C++,正确的复制运算符重载