您使用哪种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?