2013-07-23 37 views
4

我有一個類,接口,明智的,是如此簡單:我可以在編譯時強制執行此操作符調用次數嗎?

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 */ 

現在我想知道是否有一種方法可以在編譯時強制執行此操作,可以使用相同的代理技術,也可以使用其他策略。

我想實現什麼又如:強制推動任意數量的float已經傳遞給運營商後至少一個int

foo << 1 << 2 << 3.f << 4.f << 5; /* is OK */ 
foo << 1 << 2 << 3.f << 4.f; /* illegal because one `int` is needed */ 
+0

請提供預期的用例,因爲它沒有任何理由爲什麼肖恩的答案不起作用。 –

+0

你是否願意犧牲函數調用的操作符語法? – jrok

+0

您是否需要支持C++ 03?如果你可以使用C++ 11,那麼你應該使用可變參數函數模板。 –

回答

1

你可以使用一個模板代理來編碼狀態,因爲它的模板參數而不是成員。

但是,除非您使用事件的最終返回值,否則只能檢查一些條件,而不能檢查其他條件。例如,你可以檢查一個int是否在float之前被插入,或者沒有兩個float被插入到一行中,但是你不能檢查int是否在任何float之後被插入。

通常,您可以通過簡單地將插入操作符專門化爲無效狀態的無效狀態來檢測下一個插入前必須滿足的任何條件。但是你不能檢查最終狀態,因爲所有的代理必須是可破壞的(每個代理都是不同的,所以所有的代理都會被銷燬)。

+0

這正是我目前正在做的,我希望有一個我可能忽略的技巧。我接受了這個答案,因爲在這個特定的情況下,「你做不到」對我來說比對另一種方式更有用。謝謝! –

2

爲什麼不使用像一個FooPair執行偶數-ness:

struct FooPair 
{ 
    int m_x, m_y; 

    FooPair(int x, int) : m_x(x), m_y(y) 
    { 
    } 
}; 

和:

inline Foo & operator << (const FooPair &pair) 
{ 
    return *this; 
} 

使人們不得不稱其爲:

Foo foo; 
foo << FooPair(1,2) << FooPair(3,4); 

它更詳細,但將確保偶數值的傳遞。

+2

爲什麼重新創建'std :: pair'? – nijansen

+0

@Sean因爲這不是我想解決的問題。我將添加其他示例。 –

相關問題