我正在尝试使用模板制作通用选择排序功能。
我所做的是:
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;
}
然后,模板中推导出的类型T
是int [4]
一个包含四个整数的数组。在函数内部,所有这些都转换为double,代码工作正常。
但我的问题是,有没有办法让我不必将其硬编码到double
并使用类似通用类型`T&#39;。
感谢。
答案 0 :(得分:4)
您的功能不尽如人意。解决此类问题的STL方法是使用迭代器。它将允许您对C样式数组std::vector
以及提供随机访问迭代器的任何其他内容进行排序。你的函数应该采用这样的一对迭代器:
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_category
为std::random_access_iterator_tag
时,您才可以使用SFINAE技巧启用模板。或者您可以提供一个重载,将元素(或指针/迭代器)复制到std::vector
中,对其进行排序,然后将元素复制回来。有时候,这是你能做的最好的事情。
答案 1 :(得分:3)
如果您确定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;
}
}
}
}
它会自动推断出正确的类型。