0

arg12つの引数を取る関数が必要ですarg2

template<class T1, class T2>
SomeReturnType Foo(T1 arg1, T2 arg2);

引数は、ポインターまたは、std::iteratorrandom_access_iteratorの双方向イテレーターのいずれかです。Fooそれらのイテレータで何らかの操作を行い、イテレータを別のオブジェクトに返す必要がありますが、返されるイテレータは次のタイプです。

ptr, T   -> iterator< iterator_traits<T>::iterator_category >
T,   ptr -> iterator< iterator_traits<T>::iterator_category >
ptr, ptr -> iterator< random_access_iterator_tag >

random_access_iterator, random_access_iterator -> iterator< random_access_iterator_tag >

random_access_iterator, T -> iterator< iterator_traits<T>::iterator_category >
T, random_access_iterator -> iterator< iterator_traits<T>::iterator_category >
T, T                      -> iterator< bidirectional_iterator_tag> >

Foo引数のiterator_category_tagsに基づいてヘルパー関数を呼び出し、関数のオーバーロードを使用してディスパッチを処理する予定です。しかし、の戻り型を計算する方法がわかりませんFoo

編集:私は今問題を見ています。の戻り型はFoostd::iteratorから派生し、Foo関数の引数にすることができます。私が使用しているトレイトクラスはこれらのリターンタイプに特化しておらず、リターンタイプの基本クラスのみに特化しているため、これは問題です。is derived_from解決策はメタ関数を使用することだと思います。

EDIT2:タイトルは明らかに質問の内容を反映していません。これを他の人に役立つようにするために、私はより良いタイトルの提案を求めています。

4

2 に答える 2

1

これにはブースト関数の特性を使用できます。ここを見てください http://www.boost.org/doc/libs/1_52_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html

次のように使用できます。

boost::function_traits<FunctionSignature>::result_type
于 2012-11-27T10:56:31.047 に答える
1

引数の型から戻り値の型を導出する方法を探していることを正しく理解している場合は、次のような従来の方法でそれを行うことができます (最初のいくつかのケース)。

#include <iterator>

template<typename T1, typename T2>
struct ret_iterator {};

// ptr, T   -> iterator< iterator_traits<T>::iterator_category >
template<typename P, typename T>
struct ret_iterator<P *, T>
{
  typedef std::iterator<typename std::iterator_traits<T>::iterator_category, P> iter;
};

// T,   ptr -> iterator< iterator_traits<T>::iterator_category >
template<typename T, typename P>
struct ret_iterator<T, P *>
{
  typedef std::iterator<typename std::iterator_traits<T>::iterator_category, P> iter;
};

// ptr, ptr -> iterator< random_access_iterator_tag >
template<typename P>
struct ret_iterator<P *, P *>
{
  typedef std::iterator<std::random_access_iterator_tag, P> iter;
};

// random_access_iterator, T -> iterator< iterator_traits<T>::iterator_category >
template<typename T>
struct ret_iterator<std::random_access_iterator_tag, T>
{
  typedef std::iterator<typename std::iterator_traits<T>::iterator_category, T> iter;
};

template<typename P, typename T>
struct ret_iterator<std::iterator<std::random_access_iterator_tag, P>, T>
{
  typedef typename ret_iterator<std::random_access_iterator_tag, T>::iter iter;
};
于 2012-11-27T11:25:57.250 に答える