我試圖做出將舉行對象及其位置的通用容器:如何存儲一個函數對象而不訴諸於std :: function?
class Vector;
template <typename T>
class Container
{
public:
void insert(const T& t)
{
insertAtPosition(t.getPosition() ,t);
}
private:
void insertAtPosition(const Vector& v, const T& t);
...
} ;
但是,如果用戶的目標位置,吸不叫getPosition
?
如何使這個容器通用於容器內部獲取物品位置的方式?
到目前爲止,我已經考慮3種方法,他們都不理想:
- 一個
std::function<const Vector& (const T& t)>
成員添加到Container
。
這是一個乾淨的C++解決方案,但是這個函數將被非常頻繁地調用,並且可能會導致性能明顯下降。
添加函子對象到容器:
class Vector; template <typename T, typename TGetPosition> class Container { public: Container(TGetPosition getPosition): getPosition_(getPosition){} void insert(const T& t) { insertAtPosition(getPosition_(t) ,t); } private: void insertAtPosition(const Vector& v, const T& t); TGetPosition getPosition_; } ;
- 使用
#define GETTER getPosition
,用戶只需將getPosition
更改爲任何他喜歡的。這種方法有很多錯誤,我甚至不知道從哪裏開始。
我可以使用object generator idiom,使其能夠使用lambda表達式:
template <typename T, typename TGetPosition>
Container<T, TGetPosition> makeContainer(TGetPosition getter)
{
return Container<T, TGetPosition>(getter);
}
...
auto container = makeSimpleContainer<Widget>([](const Widget& w)
{
return w.tellMeWhereYourPositionMightBe();
});
不會有性能開銷,但在某些情況下獲取這種容器的類型是不可能的。例如,您無法創建一個將此類容器作爲參數的類,因爲decltype
不起作用,因爲lambda不能用於未評估的上下文中。
請問,有沒有其他方法可以做到這一點?我錯過了什麼?任何指導是最受歡迎的!
編輯:
關於解決方案2:我不知道我們如何能夠得到一個lambda函數創建一個容器的類型。一種方法是:
using TContainer = decltype(makeSimpleContainer<Widget>([](const Widget& w)
{
return w.tellMeWhereYourPositionMightBe();
});)
但是這不起作用,因爲lambda不能用在未評估的上下文中。
你是說't.getPosition()'返回一個向量? –
你能否舉一個你描述的'decltype'問題的例子,因爲它涉及到你的問題? –
@KerrekSB是的,正好。 T有一個隱含的接口。 –