其实很早就接触 boost::assign 库,只是每次嫌需要 安装一个如此大的依赖包。
我写了两个版本的 ,一个是继承 vector,然后重载 += , << 符号。
第一个版本:
template
class ListPushBack : public C
{
public:
template
ListPushBack& operator <
{
this->push_back(t);
return *this;
}
template
ListPushBack& operator,(const T& t)
{
this->push_back(t);
return *this;
}
template
ListPushBack& operator+=(const T& t)
{
this->push_back(t);
return *this;
}
};
JOB_DEFINE(grammer, ListPushBack)
{
using vec_int = ListPushBack<:vector>>;
vec_int ints;
ints += 1,2,3,4;
ints << 6,7,8,9,10;
std::for_each(ints.begin(), ints.end(), [](int v){ cout << v << endl;});
}
这个版本,使用了重载新的 ListPushBack 类型,改变了 容器类型。
打印结果如下:
![fa2005c9a6630ebcc054523f7e943299.png](https://img-blog.csdnimg.cn/img_convert/fa2005c9a6630ebcc054523f7e943299.png)
打印结果1
主要是利用了 面向对象的 “里氏替换原则”,不过改变了RTTI里面的 type_info.
并不是原生的 vector类型了。侵入了代码,不太优雅。
第二个版本,按照boost.assign的思路,简化了一个版本:
namespace kAssign {
template
class PushBack
{
public:
C& c_;
PushBack(C& c):c_(c){}
PushBack(const PushBack& kli) :c_(kli.c_) {}
template
PushBack(C& c, const T& t):c_(c)
{
c.push_back(t);
}
template
PushBack& operator <
{
c_.push_back(t);
return *this;
}
template
PushBack& operator,(const T& t)
{
c_.push_back(t);
return *this;
}
template
PushBack& operator+=(const T& t)
{
c_.push_back(t);
return *this;
}
operator C() {
return c_;
}
};
template< class V, class A, class V2 >
inline PushBack<:vector a>>
operator+=(std::vector& c, V2&& v)
{
return PushBack<:vector a>>(c, std::forward(v));
}
template< class V, class A, class V2 >
inline PushBack<:vector a>>
operator<& c, V2&& v)
{
return PushBack<:vector a>>(c, std::forward(v));
}
}
![b010a40126ceed483dda480d4c089775.png](https://img-blog.csdnimg.cn/img_convert/b010a40126ceed483dda480d4c089775.png)
优雅重载符号
测试效果:
![bab0db0be6ef9f19b877d60716010884.png](https://img-blog.csdnimg.cn/img_convert/bab0db0be6ef9f19b877d60716010884.png)
打印结果2
这个版本的优点就是 非侵入式,利用 临时对象 进行 级联调用。
其中还重载了 operator vector() 函数,可无缝用在 代码中,实现优雅的 容器初始化。
用了命名空间的原因是,防止 意想不到的 重载污染。
C++细节很多,值得品味。