11

テンプレート化されたクラスがあるとします:

template <typename T>
class foo {
  void do_someting(T obj) {
    // do something generic...
  }
};

do_something を特殊化したいが、その中で「通常の」 do_something 関数を呼び出したい:

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  // and ALSO do something generic!
}

特殊な関数内で do_something の通常バージョンを参照する方法はありますか? それとも、コードをコピーする必要がありますか?

(この正確な問題が発生しないように foo をリファクタリングできることはわかっていますが、「実際の」foo は頻繁に共有されるコードであるため、実際には変更できません。)

4

3 に答える 3

7

いいえ。特殊化は MyObj 型引数に対して存在する唯一の定義です。ただし、この方法で foo テンプレートを変更することを検討してください。これは、テンプレートの現在のユーザーに対して透過的です。

template<typename T>
class foo {
  void prelude(T &obj){ // choose a better name
    /* do nothing */
  }
  void do_something(T obj){
    prelude(obj);
    // do something generic...
  }
};

次に、プレリュードの特殊化を定義します。

template<>
void foo<MyObj>::prelude(MyObj &obj){
  // do something specific
}

これは、プライベート仮想メンバーの主な使用例と構造が似ています。(そうではありません。しかし、それがこの回答で私にインスピレーションを与えたものです。)

于 2010-11-04T17:21:11.390 に答える
1

MyObj ではなく、暗黙的に MyObj に変換される型を検討することもできますが、最善の方法はリファクタリングして、一般的なジェネリックな何かを抽出することです。

#include <iostream>
#include <boost/ref.hpp>
typedef int MyObj;


template <typename T>
struct foo {
  void do_something(T obj) {
    // do something generic...
    std::cout << "generic " << obj << '\n';
  }
};

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  std::cout << "special " << obj << '\n';
  // and ALSO do something generic!
  foo<boost::reference_wrapper<MyObj> >().do_something(boost::ref(obj));
}

int main()
{
    foo<int> f;
    f.do_something(10);
}
于 2010-11-04T17:33:07.703 に答える
0

はい、これは実際には非常に簡単です。関数のメインの汎用バージョンを、部分的に特殊化されていない「実装」汎用関数へのパススルーとして機能させ、必要に応じて初期関数の特殊化されたバージョンからそれを呼び出すことができます。

template <typename T>
class foo 
{
  void do_something(T obj) 
  {
     do_something_impl(obj);
  }

  void do_something_impl(T obj)
  {
    // do something generic...
  }
};

これで、特殊化は問題なくジェネリック バージョンを呼び出すことができます。

template<>
void foo<MyObj>::do_something(MyObj obj) 
{
  // do something specific...
  do_something_impl(obj); //The generic part
}

これは、Steve M. の回答よりも元の意図に近いと思います。この問題に直面したときに私が行うことです。

于 2012-06-08T14:01:08.823 に答える