0

さまざまなタイプのオブジェクトを保持するコンテナー (キューなど) を作成する方法はたくさんあります。std::pair<void*, int>要素を持つ最も古典的なものでelement.first、 はオブジェクトへのポインターでありelement.second、オブジェクト型にマップされます。

これらすべてのメソッド (私が知っている) には、下線オブジェクトの型を見つけるために、実行時のオーバーヘッド (たとえば、 switch on などelement.second)が含まれます。queue.pop()

私の質問は、この実行時のオーバーヘッドを完全になくすことは可能ですか? 結局のところ、オブジェクト (オブジェクトへのポインター) がキューにプッシュされる直前に、オブジェクトの型がわかっています。

4

2 に答える 2

3

要素の型が静的にわかっている場合は、テンプレート化されたデータ ストアを作成できます。

#include <queue>
#include <utility>

namespace store
{
    template <typename T> struct wrapper { static std::queue<T> data; };
    template <typename T> std::queue<T> wrapper<T>::data;

    template <typename T> void put(T const & x) { wrapper<T>::data.push(x); }

    template <typename T> void put(T && x) { wrapper<T>::data.push(std::move(x)); }

    template <typename T> T get()
    {
        T x  = wrapper<T>::data.back();
        wrapper<T>::data.pop();
        return x;
    }

    template <typename T> bool empty() { return wrapper<T>::data.empty(); }
}

使用法:

// push on the queue for decltype(a)
store::put(a);

// push on the Foo-queue
store::put(Foo(1, 'true', false));

// pop from the Bar-queue
if (!store::empty<Bar>()) { auto c = store::get<Bar>(); }
于 2013-10-19T20:07:26.497 に答える
0

スイッチを暗黙的にしたい場合は、ポリモーフィズムを使用する必要があると思います(型が共通のインターフェースを共有している場合)。オーバーロードを使用する別の方法は、ペアの 2 番目の要素を、型タグではなく、その特定の型を処理する関数へのポインターにすることです。C++11 を使用している場合は、ラムダ式を使用することもできます。

最初のオプションでは、次のような結果が得られます。

class IMyInterface
{
public:
  virtual void handle() = 0;
};

class AClass : public IMyInterface
{
public:
  virtual void handle()
  { /*handles (*this) object*/ }
};

class BClass : public IMyInterface
{
public:
  virtual void handle()
  { /*handles (*this) object*/ }
};

void handle_elements(std::vector<IMyInterface*>& v)
{
  while (!v.empty)
  {
    IMyInterface* obj = v.back();
    v.pop_back();
    obj->handle();
  }
}

2番目のオプションは次のようになります。

typedef void (*handler)(void*);

static void handle_int(void* intptr)
{
  int* iValue = (int*)intptr;
  //Handles iValue
}

static void handle_complex_object(void* ccptr)
{
  ComplexClass* ccValue = (ComplexClass*)ccptr;
  //Handles ccValue
}

void handle_elements(vector<pair<void*, handler>>& v)
{
  while (!v.empty)
  {
    pair p = v.back();
    v.pop_back();
    p.second(p.first);
  }
}

void fill_queue(vector<pair<void*, handler>>& v)
{
  v.push_back(pair<void*, handler>(new int(10), handle_int);
  v.push_back(pair<void*, handler>(new ComplexClass(), handle_complex_object);
}
于 2013-10-19T20:07:57.280 に答える