C++ 如何检查传递给函数的容器是否已排序,如果未排序,如何对其排序

C++ 如何检查传递给函数的容器是否已排序,如果未排序,如何对其排序,c++,sorting,c++11,vector,stl,C++,Sorting,C++11,Vector,Stl,我有一个我们不久前写的函数: template <class C, class T> static inline bool findClosestObject( const C& container, const TimeUnit& now, T& object ); 但是,当C是std::set或std::map时,这将无法编译。因为这类容器不允许使用std::sort fixOrder的编写方式是否可以使它只对std::vector执行操作,而不适用于其

我有一个我们不久前写的函数:

template <class C, class T>
static inline bool findClosestObject( const C& container, const TimeUnit& now, T& object );
但是,当
C
std::set
std::map
时,这将无法编译。因为这类容器不允许使用
std::sort

fixOrder
的编写方式是否可以使它只对
std::vector
执行操作,而不适用于其他容器?

更简单,应该可以解决您的问题。我下面的答案稍微复杂一点,但出于教育目的,它可能是一本有趣的读物


fixOrder是否可以这样编写,即它只对std::vector执行操作,而不对其他容器执行操作

对!!您可以使用并且助手
特征的

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 vector\n";
    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 vector\n";
    return x;
}
模板
结构是:std::false类型的
{
};
模板
结构是:std::true类型的
{
};
模板
静态内联自动修复顺序(常量C&x、C&)
->typename std::enable_if::type
{
std::cout typename std::enable_if{},const C&>::type
{

std::cout您可以只为模板函数添加部分专门化,用于
std::set
std::map

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
}
// 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;
}
//对于没有更好专门化的每个C,都会调用此函数
模板
静态内联常量C和固定顺序(常量C和容器、C和温度)
{
if(std::已排序(container.begin()、container.end())
{
返回容器;
}
其他的
{
assert(false);//提醒开发人员
//在发行版中,修复问题以使功能正常工作!
温度=容器;
排序(temp.begin(),temp.end());
返回温度;
}
}
//这一个被称为std::set
模板
静态内联常量集和固定顺序(常量集和容器、集合和临时)
{
返回容器;
}
//这一个被称为std::map
模板
静态内联常量映射和固定顺序(常量映射和容器、映射和临时)
{
返回容器;
}

有关于模板函数重载解析的详细信息。

为什么不为
std::vector
添加重载?顺便说一句,由于目标是确保容器始终被排序,所以让非专用版本进行排序可能更安全,而让
设置
/
映射的专用版本则不会做任何事情(然后我们可以在需要时添加一些专门的版本,但我们保留默认行为以静默排序“全部”)。更新您的帖子以反映这一点可能是有意义的。@jpo38同意,will fixNice.Thanx再次感谢您的帮助。
// 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;
}