我有一个类,在接口方面,就像这样简单:
struct Foo
{
inline Foo & operator << (int i)
{
return *this;
}
};
然后我可以通过以下方式使用它:
Foo foo;
foo << 1 << 2 << 3 << 4;
现在我想限制这个运算符的使用。例如,我希望它在序列点之间被调用偶数次。
我目前使用内部代理类来解决这个问题。创建一个临时对象,在控制序列结束时将其销毁,并检查操作符被调用了多少次:
struct Foo
{
inline Foo() : m_count(0) {}
private:
struct FooProxy
{
friend struct Foo;
inline ~FooProxy();
inline struct Foo & operator << (int i);
private:
inline FooProxy(struct Foo &foo) : m_foo(foo) {}
struct Foo &m_foo;
};
public:
inline FooProxy operator << (int i);
private:
int m_count;
};
inline Foo::FooProxy Foo::operator << (int i)
{
++m_count;
return FooProxy(*this);
}
inline Foo & Foo::FooProxy::operator << (int i)
{
++m_foo.m_count;
return m_foo;
}
inline Foo::FooProxy::~FooProxy()
{
assert(m_foo.m_count % 2 == 0);
}
有一些警告,但它主要是完成这项工作:
Foo foo;
foo << 1 << 2 << 3 << 4; /* is OK */
foo << 1 << 2 << 3; /* triggers an assert */
现在我想知道是否有办法在编译时强制执行此操作,或者使用相同的代理技术,或者使用其他策略。
我想要实现的另一个示例:在将int
任意数量float
传递给操作员之后强制推送至少一个:
foo << 1 << 2 << 3.f << 4.f << 5; /* is OK */
foo << 1 << 2 << 3.f << 4.f; /* illegal because one `int` is needed */