2014-10-22 34 views
0

維基百科上有一個有趣的模板,用於Properties沒有繼承的回收成員功能

該模板提供了一些有趣的內容,因爲它允許提供圍繞成員訪問的邏輯。在此基礎上,我們可以很容易建立這樣的事情:

struct Ranged { 
    ranged_property<float,0,1> unit_property; 
}; 

unit_property範圍被強制爲[0,1]內。

我們如何提供一個類似的功能取決於託管類的成員?例如:

struct AdjustableRanged { 
    float max; 
    ranged_property<float,0,max> influenceable_property; 
}; 

influenceable_property範圍受到的max的值影響。請記住,我們的目標是讓這種模板在很多不同的類中循環使用。相關概念是mixin和裝飾器。

它可以用宏來完成......但我覺得有必須是一個更好用的C++解決方案。


編輯補充:我覺得這可以通過保存到ranged_property模板中的成員的引用來完成......但是這似乎是空間,這將是有效的恆定值,完全是浪費; ETA;一個const引用實際上可以達到目的,但是,我需要進行調查。

+1

爲什麼你要'max'作爲'AdjustableRange'中的獨立數據成員,而不是將其封裝爲'ranged_property'對象的成員(然後將其規定給構造函數)? – 2014-10-22 02:53:54

+2

我不確定參考會浪費空間。它是實現定義的,實際上如何實現引用,但最終它們只是另一個名稱,因此與使用原始變量名相比,編譯器輸出中可能沒有任何可見的變化。也許,對主要編譯器的內部工作更瞭解的人可以對此進行評論... – Oguk 2014-10-22 02:56:27

+0

模板是編譯時結構,它們不能用運行時值初始化。 – 2014-10-22 03:16:34

回答

2

我們在評論中討論的後續行動,似乎功能可以與這樣的指針到成員模板參數來實現的(但請參見下面的注意事項):

#include <iostream> 

template<typename C, typename T, T C::*m> 
struct PrintMember { 
    C& obj; 
    PrintMember(C& obj) : obj(obj) {}; 
    void print() { std::cout << "Member of containing class: " << obj.*m << std::endl; }; 
}; 

struct TestClass { 
    int data; 
    PrintMember<TestClass, int, &TestClass::data> pm; 
    TestClass() : pm(*this){}; 
}; 

int main() 
{ 
    TestClass tc; 
    tc.data = 5; 
    tc.pm.print(); 
} 

這隻能表明,可以訪問包含對象的成員。有幾件事情,這種做法並沒有解決:

  • 如果你真的只需要訪問一個成員,這是不值得的,因爲你有一個參考保存到*this在PrintMember成員能夠將指針取消引用到成員。所以它實際上並不能解決存儲參考的問題。您也可以在構造函數中傳遞對成員變量本身的引用。但是,如果您需要訪問多個成員,則允許您只存儲一個參考(至*this),並仍然可以訪問所有這些成員。

  • 指定模板參數PrintMember並在構造函數中使用*this初始化PrintMember成員變量非常乏味。也許,一些聰明的模板參數推導可以幫助在這裏,但我還沒有嘗試過,我甚至不知道它會得到任何簡單...

在某些特殊情況下,有可能是髒的方式訪問封閉類的「this」指針而不明確保存它,就像在this answer中使用offsetof的答案一樣,但是我的感覺告訴我你想要一個便攜式的,不易碎的東西......