0

私は2つのパラメータと派手なpush_backメソッドを持つテンプレートクラスを持っています:

template<class Element, void (Element::*doWhenPushingBack)()> 
class StorableVector {
    public:
        ...
        void push_back(Handle< Element > e) {
            this->push_back_< IsNull<static_cast<void *>(doWhenPushingBack)>::value >(e);
        };
    private:
        template <int action> void push_back_(Handle< Element > e);
        template<> void push_back_<0>(Handle< Element > e) { m_elements.push_back(e); };
        template<> void push_back_<1>(Handle< Element > e) { ((*e).*(doWhenPushingBack))(); m_elements.push_back(e); };
        std::vector< Handle< Element > > m_elements;
};

それは使用しています

template <void * param>   class IsNull {
public:
    enum {value = 0 };
};
template <>   
class IsNull<NULL> {
public:
    enum {value = 1 };
};

このコードはコンパイルされません ( エラー C2440: 'static_cast' : cannot convert from 'void (__thiscall pal::InterfaceFunction::* const )(void)' to 'void *' 1> この変換が行われるコンテキストはありません可能です)。

実行時に (!!doWhenPushingBack) チェックを実行すると問題なく動作しますが、少しばかげているように見えます。コンパイル時に入力をチェックする必要があります。

手伝ってくれる?ありがとう。

4

2 に答える 2

0

次のような同様の動作をする可能性があります。

class Fred
{
public:
  void yabadabadoo() { std::cout << "yabadabadoo" << std::endl; }

  void wilma() { std::cout << "Wilmaaaaaaa!" << std::endl; }
};


template <typename E>
struct Nothing
{
  void operator()(E const &) const { }
};

template <typename E, void (E::* memfun)()>
struct Something
{
  void operator()(E e) const { (e.*memfun)(); }
};

template <typename E, typename Pre = Nothing<E>>
class MyVec
{
public:
  void push_back(E e) { Pre()(e); m_vec.push_back(e); }

protected:
private:
  std::vector<E> m_vec;
};


void stackoverflow() 
{
  MyVec<Fred> silent;
  MyVec<Fred, Something<Fred, &Fred::yabadabadoo>> yab;
  MyVec<Fred, Something<Fred, &Fred::wilma>> wil;

  Fred fred;
  silent.push_back(fred);
  yab.push_back(fred);
  wil.push_back(fred);
}

本格的な最適化コンパイラ(つまり、20年以内)は、Nothing :: operator()の空の関数呼び出しを最適化する必要があります。

于 2012-08-22T11:30:18.627 に答える
0

あなたは書ける

    void push_back(Handle< Element > e) {
        this->push_back_< doWhenPushingBack == 0 >(e);
    };

IsNullテンプレートを使用する必要はありません。

于 2012-08-22T11:07:56.757 に答える