3
struct A // some class
{
  void method(); // non-static member method
  static void function(); // static member method
};
void function(); // global function
vector<A> vi; // any such `std` like container

Iterate()以下の方法で呼び出すことができる関数(たとえば)が必要です。

Iterate(vi, &A::method);  // (1)
Iterate(vi, &A::function); // (2a)
Iterate(vi, &function); // (2b)

(2a) と (2b) はまったく同じです。

Iterate()(1) と (2) のプロトタイプは以下のようになります。

template<typename Container, typename Method>
void Iterate (Container &container, Method method); // for (1)

template<typename Container, typename Function>
void Iterate (Container &container, Function function); // for (2a), (2b)

当然、両方ともまったく同じであり、コンパイラ エラーが発生します。両方の機能が共存できるようにする C++03 で
オーバーロード/特殊化する方法はありますか?Iterate()

4

1 に答える 1

1

1 つの関数を他の関数より具体的にすることができます。

template<typename Container, typename Functor>
void Iterate (Container &container, Functor fun); 

template<typename Container, typename R, typename ..Args>
void Iterate (Container &container, R (Container::value_type::*fun)(Args...));

最初のテンプレートは通常の関数、関数オブジェクト、および静的メンバー関数に対して機能しますが、2 番目のテンプレートは非静的メンバー関数に対してのみ機能します。

C++03 では、次のようにオーバーロードを記述して、可変個引数テンプレートをシミュレートできます。

template<typename Container, typename R>
void Iterate (Container &container, R (Container::value_type::*fun)());

template<typename Container, typename R, typename Arg>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg));

template<typename Container, typename R, typename Arg1, typename Arg2>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg1, Arg2));

//add more overloads to handle member functions 
//that take 3 or more arguments

もちろん、それらを別の方法で実装する必要がある場合。たとえば、メンバー関数を呼び出す構文は次のようになります(obj.*fun)(a1,a2,a3);が、ファンクター呼び出し構文は justfun(a1,a2,a2)です。関数(メンバーまたはファンクター)に渡す引数はわかりません。これは実際のコードではなく、構文を調べたいだけだと思います。

重要な点の 1 つは、obj(コンテナーから) ファンクターを呼び出す必要がないことですが、引数として渡すことはできます。

于 2012-12-29T15:03:19.693 に答える