C++ 模板特化问题

标签 c++ templates template-specialization

我在使用 C++ 中的专用函数模板时遇到问题。我正在编写一个比较函数模板,它将用于对不同数据类型进行排序。这是我的部分代码:

template < typename T >
bool cmp(T a, T b)
{
    std::cout<<"normal"<<std::endl;
    return(a >= b);
}

template < typename T >
bool cmp(T* a, T* b)
{
    std::cout<<"pointer"<<std::endl;
    return(*a >= *b);
}

所以我可以按值和点值排序。但是,当我尝试将此函数传递给 sort 时:

double* double_array[]={d1,d2,d3,d4,d5};
nsp::sort(double_array, 5, nsp::cmp<double*>);

编译错误:

error: no matching function for call to 'sort(double* [5], int, <unresolved overloaded function type>)'|
template argument deduction/substitution failed:|
could not resolve address from overloaded function 'cmp<double*>'|

为什么?我明确提供模板类型!

作为引用,我的排序函数模板如下所示:

namespace nsp {
    ...

    template < typename T, typename CMP>
    void sort(T array[], int n, CMP cmp=CMP())
    {
        for(int j = 0;j < n-1; j++)
            for(int i = 0; i < n-1; i++)
              if(cmp(array[i],array[i + 1]))
                  std::swap(array[i], array[i + 1]);
    }
}

最佳答案

您收到“未解析的重载函数类型”编译错误的原因是,很简单,您正试图将重载函数传递给 sort() .你提供cmp<double*>但仍有两个 cmp<double*>功能:需要两个的乐趣double* s(你的第一个函数模板)和需要两个 double** 的那个s(你的第二个)。编译器不清楚你指的是哪一个。

你可以直接使用 cmp到你想要的那个:

static_cast<bool(*)(double*, double*)>(nsp::cmp<double>) // note you want cmp<double>,
                                                         // not cmp<double*>

请注意,混淆的一个来源是您认为您专攻 cmp .你不是。函数模板没有部分特化。你重载了它。函数模板唯一允许的特化是显式:

template <>
bool cmp(double* a, double* b) {
    std::cout<<"pointer"<<std::endl;
    return(*a >= *b);
}

这将使 nsp::cmp<double*>毫不含糊,并且会完全按照您的期望行事。在这种情况下。您必须分别为每种类型执行此操作。相反,您可以提供类模板比较器,因为类模板可以部分特化:

template <typename T> struct Cmp { .. };     // "normal"
template <typename T> struct Cmp<T*> { .. }; // "pointer"

这样,你就可以通过 nsp::Cmp<double*>() ,这在我看来要干净得多。

关于C++ 模板特化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30040090/

相关文章:

c# - 使用策略模式在 C# 上实现类似行为的多参数 C++ 模板

c++ - 部分特化成员函数实现

c++ - 这个异或有什么错误

c++ - 如何将 bool 转换为 BOOL?

c++ - 在 GCC 中工作的外联构造函数模板在 Clang 中失败

C++ 继承模板依赖类型

c++ - 模板代码中的默认类型参数错误

c++ - 创建一个 Variant 类和 std::map<Variant, Variant>

c++ - 在方法上调用方法 C++

html - 以当今现代方式使用 "caption"HTML 元素的最合适方式是什么?