2

関数を複数の反復子にマップする関数を作成しようとしています。それは次のようなものになります

template <class Fun>
fun_over_variadic_args(Fun fun) { }

template <class Fun, class First, class Rest...> 
fun_over_variadic_args(Fun fun, First& first, Rest&... rest) { 
  fun(first); 
  fun_over_variadic_args(fun, rest...);
}

namespace { 
  template <class T> struct thunk_inc { 
    decltype(T::operator++()) operator()(T& t) { return ++t; } 
  }; 
}

template <class Fun, class MainIterator, class RestOfIterators...>
std::tuple<MainIt&, RestOfIts&...> map_over_iterators(Fun fun, MainIt& it, MainIt& end, RestOfIts&... rest) {
const thunk_inc();
for (; it!=end; fun_over_variadic_args(thunk_inc, it, rest...)) {
      // Do something
    }
}

fun_over_variadic_args の関数 Fun をテンプレート化する必要があるという問題が発生します。これは、ラムダにすることも、グローバル名前空間を汚染するローカル関数オブジェクトにすることもできないことを意味します。

誰かがこれに対するより良い解決策を知っていますか?
ありがとう

編集:すべての関数呼び出しをインライン化する可能性を維持するソリューションが優先されるように、可能な限り最大の速度が必要であることに注意してください。

Edit2:匿名の名前空間を使用して、関数 Fun のスコープを 1 つのファイルに制限できることに気付きました。解決策が存在する場合でも、より適切な解決策を知りたいです。

代替ソリューション結果を別の関数に渡す限り、関数 fun を可変引数パックに適用できることがわかりました。したがって、すべての引数に適用したい関数funがある場合、次のようなことができます

template <class... T>
void foo(T... t) { }

template <class... Arg>
void test(Arg... arg) {
  foo(fun(arg)...); // Works!
  fun(arg)...; // Doesn't work! 
}

代替ソリューションの明確化ただし、これを使用すると、 fun は void を返すことができません

4

1 に答える 1

1

さて、問題の追加の説明を考えると、おそらく次のような可変要素が実行されます。

template <typename ItHead, typename... ItTail>
void advance_iterators(ItHead & it, ItTail ...others)
{
  ++it;
  advance_iterators(others...);
}

template <typename It>
void advance_iterators(ItHead & it)
{
  ++it;
}

template <typename Fun, typename ItMain, typename ...ItOthers>
apply_helper(Fun & f, ItMain it, ItOthers ...others)
{
   f(*it);
   apply_helper(f, others...);
}

template <typename Fun, typename ItMain, typename ...ItOthers>
apply_helper(Fun & f, ItMain it)
{
   f(*it);
}

template <typename Fun, typename ItMain, typename ...ItOthers>
apply (Fun & f, ItMain begin, ItMain end, ItOthers ...others)
{
  while (begin != end)
  {
    apply_helper(f, begin, others...);
    advance_iterators(begin, others...);
  }
}

ここでの明らかな制限Funは、イテレータのすべての値型で機能しなければならないことと、範囲が等しくなければならないことです。関数オブジェクトは参照によって渡され、好みに合わせて変更できます。

更新:f私が誤解していて、すべての値を同時に操作したい場合は、それらすべてのイテレータを使用する関数を削除してapply_helper呼び出して作成する必要があります。f(begin, others...)f

于 2011-06-14T20:45:59.387 に答える