如何检查传递给函数的容器是否已排序,如果没有,则对其进行排序
How to check if a container passed to a function is sorted and sort it if not
我有我们前段时间写的这个函数:
template <class C, class T>
static inline bool findClosestObject( const C& container, const TimeUnit& now, T& object );
C
是 T 元素的容器TimeUnit
是一个封装日期和时间的类T
是具有TimeUnit
信息
的对象
此函数在容器中执行二分搜索(使用std::lower_bound
)以查找最接近now
的对象。
当我们进行二叉搜索时,必须对容器进行排序。这个函数在许多地方与许多种类的容器(C
可以std::vector
、std::set
、std::map
......)一起使用。有时我们使用排序std::vector
而不是std::set
因为它们的内存管理更快,并且还用于历史问题以及与使用向量的其他代码段的兼容性。
问题是我在代码中找到了一个地方,开发人员使用未排序的容器调用findClosestObject
......好虫...而且我无法安全地确定所有可以做到这一点的地方。
所以我现在需要通过在这种特定情况下对容器进行排序来防止这种情况(会很慢,但至少可以工作,并且保证函数返回我们希望它返回的内容)
所以我尝试修改我的函数:
template <class C, class T>
static inline const C& fixOrder( const C& container, C& temp )
{
if ( std::is_sorted( container.begin(), container.end() )
{
return container;
}
else
{
assert( false ); // to alert developper
// in Release, fix the issue to have function work!
temp = container;
std::sort( temp.begin(), temp.end() );
return temp;
}
}
template <class C, class T>
static inline bool findClosestObject( const C& originalContainer, const TimeUnit& now, T& object )
{
C temp;
const C& container = fixOrder( originalContainer, temp );
...
// leave old code unchanged
}
但是当C
是std::set
或std::map
时,这无法编译。因为std::sort
不允许使用这种容器...
是否可以以这样一种方式编写fixOrder
,即它只会为std::vector
而不是为其他容器做事?
您可以只为std::set<T>
添加部分专用化,为模板函数添加std::map<T1,T2>
:
// This one is called for every C not having a better specialization
template <class C>
static inline const C& fixOrder( const C& container, C& temp )
{
if ( std::is_sorted( container.begin(), container.end() ))
{
return container;
}
else
{
assert( false ); // to alert developper
// in Release, fix the issue to have function work!
temp = container;
std::sort( temp.begin(), temp.end() );
return temp;
}
}
// This one is called for std::set<T>
template<class T>
static inline const set<T>& fixOrder( const set<T>& container, set<T>& temp )
{
return container;
}
// This one is called for std::map<T1, T2>
template<class T, class T2>
static inline const map<T, T2>& fixOrder( const map<T, T2>& container, map<T, T2>& temp )
{
return container;
}
此答案包含有关模板函数重载解析的详细信息。
alexeykuzmin的回答更简单,应该可以解决你的问题。我下面的答案稍微复杂一些,但出于教育目的,这可能是一个有趣的读物。
fixOrder是否可以以这样一种方式编写,即它只会为std::vector而不是为其他容器做事?
是的!您可以使用std::enable_if
和帮助程序is_specialization_of
特征:
template <typename, template <typename...> class>
struct is_specialization_of : std::false_type
{
};
template <template <typename...> class TTemplate, typename... Ts>
struct is_specialization_of<TTemplate<Ts...>, TTemplate> : std::true_type
{
};
template <class C>
static inline auto fixOrder(const C& x, C&)
-> typename std::enable_if<is_specialization_of<C, std::vector>{}, const C&>::type
{
std::cout << "C is a vectorn";
return x;
}
template <class C>
static inline auto fixOrder(const C& x, C&)
-> typename std::enable_if<!is_specialization_of<C, std::vector>{}, const C&>::type
{
std::cout << "C is not a vectorn";
return x;
}
使用上面的代码...
int main()
{
std::vector<int> v;
std::set<int> s;
fixOrder(v, v);
fixOrder(s, s);
}
。将打印:
C 是向量
C 不是向量
魔杖盒示例
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 是否有任何C++功能可以对地图进行排序?
- MOVNTI 存储是否相对于由同一线程创建的其他 MOVNTI 存储重新排序?
- 选择排序时交换函数调用的数量和完成的交换次数是否相同?
- 是否可以在调用链接器时强制 CMake 重新排序参数?
- 检查向量是否使用除法和阻抗算法进行排序
- 是否使用cv::Point2f类型重载std::排序
- "<"满足严格的弱排序是否意味着不需要"=="定义?
- 在这种单例实施中,是否可以对两个商店重新排序?
- 如何检查队列是否使用 STL 排序
- 确定数组是否可以旋转 3 个连续的数组元素进行排序?
- 是否有用于排序和查找 c++ 中是否已存在的值的函数?
- 我的选择排序代码是否存在导致它跳过数组中的元素的问题?
- 是否可以在条件之前对加载或存储进行重新排序?
- 查看数字是否包含在未排序的双数字间隔内的最有效方法?
- 构造函数的初始值设定项列表中的函数调用是否按顺序排序?
- 此并发快速排序实现是否正确?
- 是否存在用于按以下方式对两个范围进行排序和分区的标准算法?
- 在独立类中对公共非虚拟方法重新排序是否会破坏 ABI
- STL排序是否支持UTF8 ?