簡體   English   中英

如何不使用std :: function來存儲函數對象?

[英]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種方法,但都不理想:

  1. std::function<const Vector& (const T& t)>成員添加到Container

這是一個干凈的C ++解決方案,但是該函數將被非常頻繁地調用,並且可能導致性能顯着下降。

  1. 將仿函數對象添加到容器中:

     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。

  1. 使用#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM