C ++模板专业化问题

时间:2015-05-04 21:13:31

标签: 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]);
    }
}

1 个答案:

答案 0 :(得分:3)

您使用&#34;未解决的重载函数类型&#34;导致编译错误的原因是因为,很简单,你试图将重载函数传递给sort()。您提供了cmp<double*>,但仍然有两个 cmp<double*>函数:两个double* s(您的第一个函数模板)带来的乐趣和带两个double**的函数{1}} 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*>(),这在我看来更清晰。