在模板中推断临时类型

Deduce type for temporary in template

我正在尝试使用模板创建一个通用的选择排序函数。

我做的是:

template<typename T>
    void nrsort(T &a,int size)
    {
        // Applying Selection Sort
        double temp; // This is the issue

        for (int i = 0; i < size ; i++)
        {
            double minimum=a[i];  //  This one too
            for (int j = i+1; j < size ; j++)
            {
                if(a[j]<minimum)
                {
                    temp=a[i];;
                    a[i]=a[j];
                    minimum=a[j];
                    a[j]=temp;
                }
            }
        }


    }

我想要一个可以对整数、浮点数、字符等进行排序的通用模板。

上面提到的代码有效,但主要问题是我对 double temp;double minimum 进行了硬编码,并且每次都会进行数据转换。

如果我按如下方式编写 main 方法:

int main()
{
    int values[]={4,3,6,1};




    nrsort(values,4);

    for (int i = 0; i < 4 ; i++)
    {
        cout<<values[i]<<"\t";
    }


    return 0;
}

那么在模板中推导出的类型 Tint [4] 一个由四个整数组成的数组。在函数内部,所有这些都转换为 double,代码工作正常。

但我的问题是,有什么方法可以让我不必将其硬编码为 double 并使用类似通用类型“T”的东西。

谢谢。

如果固定 temp 的范围,您可以简单地使用 auto:

template<typename T>
    void nrsort(T &a,int size)
    {
        // Applying Selection Sort


        for (int i = 0; i < size ; i++)
        {
            auto minimum=a[i];  //  This one too
            for (int j = i+1; j < size ; j++)
            {
                if(a[j]<minimum)
                {
                    auto temp=a[i];;
                    a[i]=a[j];
                    minimum=a[j];
                    a[j]=temp;
                }
            }
        }


    }

它会自动推断出正确的类型。

您的函数没有达到应有的通用性。解决此类问题的 STL 方法是使用 iterators。它将允许您对 C 风格的数组、std::vectors 和任何其他提供随机访问迭代器的东西进行排序。你的函数应该采用一对像这样的迭代器:

template <typename IteratorT>
void
my_sort(IteratorT begin, IteratorT end);

然后,如果你#include <iterator>,你可以像这样

查询值类型(即如果你取消引用一个IteratorT你会得到什么)
using ValueT = typename std::iterator_traits<IteratorT>::value_type;

现在,ValueT 是您的类型的类型别名。

如果您愿意,可以提供一个方便的包装函数:

#include <utility>  // for std::begin() and std::end()

template<typename ContainerT>
void
my_sort(ContainerT& container)
{
  using std::begin;
  using std::end;
  my_sort(begin(container), end(container));
}

存在一个问题:这些函数模板会过于急切地匹配,即使迭代器不是随机访问迭代器。仅当 std::iterator_traits<IteratorT>::iterator_categorystd::random_access_iterator_tag 时,您才可以使用 SFINAE 技巧来启用您的模板。或者您可以提供一个重载,将元素(或指向它们的指针/迭代器)复制到 std::vector 中,对其进行排序,然后将元素复制回来。有时,这是您能做的最好的事情。