1

次のようなコンパイル時のイテレータを実行しようとしています:

meta::reverse_iterator<2, 9>::iterate(callback());
meta::reverse_iterator<4, 7>::iterate(callback());
std::cout << "-----------------" << std::endl;
meta::iterator<2, 9>::iterate(callback());
meta::iterator<4, 7>::iterate(callback());

struct callback {
  template <int i>
  void operator()() {
    std::cout << "print !!" << i << std::endl;
  }
};

そして、これは私がメタイテレータを書いた方法です:

namespace meta {
    template <int Begin, int End, bool done = false>
    struct reverse_iterator {
        template <typename F>
        static void iterate(F f) {
            f.template operator()<End>();
            reverse_iterator<Begin, End-1, Begin == End-1>::iterate(f);
        }
    };

    template <int Begin, int End>
    struct reverse_iterator<Begin, End, true> {
        template <typename F>
        static void iterate(F) {}
    };

    template <int Begin, int End, bool done = false>
    struct iterator {
        template <typename F>
        static void iterate(F f) {
            iterator<Begin, End - 1, Begin == End - 1>::iterate(f);
            f.template operator()<End - 1>();
        }
    };

    template <int Begin, int End>
    struct iterator<Begin, End, true> {
        template <typename F>
        static void iterate(F) {}
    };

}

現在、私はイテレータ呼び出しをoperator()<N>行っていますが、ユーザーがテンプレート パラメータ (実行時引数としてではなく) を指定して任意の関数を呼び出せるようにしたいのです<N>が、どうすれば実現できますか?

実際の関数の代わりに bind の関数オブジェクトを呼び出すため、これもboost::bind機能しません。したがって、提供された関数にデフォルトのパラメーターを渡す方法が必要です。

4

1 に答える 1

0

私の知る限り、直接行うことはできませんが、本当に必要な場合は、traitsメンバー関数を呼び出すクラスを使用できます。また、メンバー関数ごとに異なる特性を記述します。

struct function_operator_call_trait {
    template< int N, class T >
    void call( T& t ) {t.template operator()<N>();}
};
template< class Arg1, class Arg2 >
struct foo_call_trait {
    foo_call_trait( Arg1&& arg1 ) : a1( std::move(arg1) ) {}
    foo_call_trait( Arg1&& arg1, Arg2&& arg2 )
        : a1( std::move(arg1) ), a2( std::move(arg2) ) {}
    template< class T, int N >
    void call( T& t ) {t.template foo<N>(a1, a2);}
    Arg1 a1;
    Arg2 a2;
};
template <int Begin, int End, class traits = function_operator_call_trait, bool done = false>
struct iterator{
    iterator() {}
    iterator( traits const& t ) : t_( t ) {}
    iterator( traits&& t ) : t_( std::move(t) ) {}
    template<typename F>
    static void iterate(F f){
        iterator<Begin, End-1, traits, Begin == End-1>::iterate(f);
        t_.call<End-1>( f );
    }
    traits t_;
};
typedef iterator<2, 9> fc_iterator;
typedef foo_call_trait<int, float> foo_traits;
typedef iterator<2, 9, foo_traits> foo_iterator( foo_traits(1, 2) );
于 2012-10-31T16:26:43.020 に答える