[英]How to store a function object without resorting to 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_; } ;
我可以使用對象生成器慣用法來使用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。
#define GETTER getPosition
,用戶只需將getPosition
更改getPosition
自己喜歡的內容即可。 這種方法有很多問題,我什至不知道從哪里開始。 拜托,還有其他方法嗎? 我有什么想念的嗎? 任何指導都是最歡迎的!
編輯:
關於解決方案2:我不知道如何獲得使用lambda函數創建的容器的類型。 一種方法是:
using TContainer = decltype(makeSimpleContainer<Widget>([](const Widget& w)
{
return w.tellMeWhereYourPositionMightBe();
});)
但這是行不通的,因為不能在未經評估的上下文中使用lambda。
合理可用的選擇是期望上下文具有position_for()
:
template <class T> struct Container {
size_t insert(T const& x) {
insertAtPosition(position_for(x), x);
}
};
Vector const& position_for(const Widget& w) {
return ...;
}
Container<Widget> c;
c.insert(Widget());
...但是容器在其中從業務對象生成密鑰的設計通常不能很好地飛行,因為要查找該對象可能需要做一個虛擬對象,這可能很昂貴。
即使您需要創建一個包含容器的類,您的第二個解決方案似乎仍然可以工作:
template <typename Container>
struct SomeClass {
SomeClass(const Container &container) : container(container) { }
Container container;
};
int main()
{
auto container = makeSimpleContainer<Widget>([](const Widget& w)
{
return w.tellMeWhereYourPositionMightBe();
});
SomeClass<decltype(container)> test(container);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.