您使用哪种C ++标准库包装函数?

今天早上提出的这个问题使我想知道C ++标准库中缺少哪些功能,以及如何利用包装函数填补空白。 例如,我自己的实用程序库具有此向量附加功能:

template <class T>
std::vector<T> & operator += ( std::vector<T> & v1,
                               const std::vector <T> & v2 ) {
    v1.insert( v1.end(), v2.begin(), v2.end() );
    return v1;
}

和这个清除(或多或少)任何类型 - 对std :: stack之类的东西特别有用:

template <class C>
void Clear( C & c ) {
    c = C();
}

我还有一些,但我对你使用哪一种感兴趣? 请限制封装函数的答案 - 即不超过几行代码。


boost :: array

包含 (容器,val)(很简单,但方便)。

template<typename C, typename T>
bool contains(const C& container, const T& val) {
   return std::find(std::begin(container), std::end(container), val) != std::end(container);
}

remove_unstable(开始,结束,值)

std :: remove的更快版本,但不保留其余对象的顺序。

template <typename T> 
T remove_unstable(T start, T stop, const typename T::value_type& val){  
    while(start != stop) {      
        if (*start == val) {            
            --stop;             
            ::std::iter_swap(start, stop);      
        } else {            
            ++start;        
        }   
    }   
    return stop; 
}

(在pod类型的向量(int,float等)的情况下,几乎所有对象都被删除,std :: remove可能会更快)。


很多时候,我会将vector作为一组项目,而不是按特定的顺序排列(显然,当我不需要快速的时候,就是这个元素在这里设置的检查)。 在这些情况下,调用erase()会浪费时间,因为它会重新排列元素,我不关心顺序。 这就是当下面的O(1)函数派上用场时 - 只需将最后一个元素移动到您想要删除的位置即可:

template<typename T>
void erase_unordered(std::vector<T>& v, size_t index)
{
    v[index] = v.back();
    v.pop_back();
}

template < class T >
class temp_value {
    public :
        temp_value(T& var) : _var(var), _original(var) {}
        ~temp_value()        { _var = _original; }
    private :
        T&  _var;
        T   _original;
        temp_value(const temp_value&);
        temp_value& operator=(const temp_value&);
};

好的,因为看起来这不像我想象的那么直截了当,下面是一个解释:
在其构造函数temp_value存储对变量的引用和变量原始值的副本。 在其析构函数中,它将引用的变量恢复为其原始值。 因此,无论您对构造和销毁之间的变量做了什么,当temp_value对象超出范围时它都会重置。
像这样使用它:

void f(some_type& var)
{
  temp_value<some_type> restorer(var); // remembers var's value

  // change var as you like
  g(var);

  // upon destruction restorer will restore var to its original value
}

这是另一种使用示波器技巧的方法:

namespace detail
{
    // use scope-guard trick
    class restorer_base
    {
    public:
        // call to flag the value shouldn't
        // be restored at destruction
        void dismiss(void) const
        {
            mDismissed = true;
        }

    protected:
        // creation
        restorer_base(void) :
        mDismissed(false) 
        {}

        restorer_base(const restorer_base& pOther) :
        mDismissed(pOther.is_dismissed())
        {
            // take "ownership"
            pOther.dismiss();
        }

        ~restorer_base(void) {} // non-virtual

        // query
        bool is_dismissed(void) const
        {
            return mDismissed;
        }

    private:
        // not copy-assignable, copy-constructibility is ok
        restorer_base& operator=(const restorer_base&);

        mutable bool mDismissed;
    };

    // generic single-value restorer, could be made 
    // variadic to store and restore several variables
    template <typename T>
    class restorer_holder : public restorer_base
    {
    public:
        restorer_holder(T& pX) :
        mX(pX),
        mValue(pX)
        {}

        ~restorer_holder(void)
        {
            if (!is_dismissed())
                mX = mValue;
        }

    private:
        // not copy-assignable, copy-constructibility is ok
        restorer_holder& operator=(const restorer_holder&);

        T& mX;
        T mValue;
    };
}

// store references to generated holders
typedef const detail::restorer_base& restorer;

// generator (could also be made variadic)
template <typename T>
detail::restorer_holder<T> store(T& pX)
{
    return detail::restorer_holder<T>(pX);
}

这只是一个更多的锅炉代码,但允许更清洁的用法:

#include <iostream>

template <typename T>
void print(const T& pX)
{
    std::cout << pX << std::endl;
}

void foo(void)
{
    double d = 10.0;
    double e = 12.0;
    print(d); print(e);

    {
        restorer f = store(d);
        restorer g = store(e);

        d = -5.0;
        e = 3.1337;
        print(d); print(e);

        g.dismiss();
    }

    print(d); print(e);
}

int main(void)
{
    foo();

    int i = 5;
    print(i);

    {
        restorer r = store(i);

        i *= 123;
        print(i);
    }

    print(i);
}

尽管如此,它消除了它在课堂上使用的能力。


这是获得相同效果的第三种方法(不会遇到可能抛出析构函数的问题):

执行:

//none -- it is built into the language

用法:

#include <iostream>

template <typename T>
void print(const T& pX)
{
    std::cout << pX << std::endl;
}

void foo(void)
{
    double d = 10.0;
    double e = 12.0;
    print(d); print(e);

    {
        double f(d);
        double g(e);

        f = -5.0;
        g = 3.1337;
        print(f); print(g);

        e = std::move(g);
    }

    print(d); print(e);
}

int main(void)
{
    foo();

    int i = 5;
    print(i);

    {
        int r(i);

        r *= 123;
        print(r);
    }

    print(i);
}
链接地址: http://www.djcxy.com/p/72969.html

上一篇: Which C++ Standard Library wrapper functions do you use?

下一篇: What's the point of const pointers?