1
    char foo()
    {
         std::cout<<"foo()"<<std::endl;
         return 'c';
    }              
    void foo(char &&i)
    {
         std::cout<<"foo(char &&i)"<<std::endl;
    }
    struct pipe {};
    template<class OP>
    struct Flow;
    template<>
    struct Flow<pipe> {
         template<class L,class R>
         static  auto apply(L&& l,R &&r)->decltype(r(std::forward<L>(l))) {
              return r(std::forward<L>(l));
         }
    };
    template<class L,class R,class E>
    struct Pipe;
    template<class F,class...ARGS>
    auto eval(F& f,ARGS&&... arg)->decltype(f(std::forward<ARGS>(arg)...))
    {
        return f(std::forward<ARGS>(arg)...);
    }
    template<class L,class R,class E,class...ARGS>
    auto eval(Pipe<L,R,E>&f,ARGS&&... arg)->decltype(Flow<E>::apply(eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs))
    {
        return Flow<E>::apply(eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs);
    }
    template<class L,class R,class E>
    struct Pipe {
         L lhs;
         R rhs;
         Pipe(L &l,R& r):lhs(l),rhs(r) {
         }
          template<class...ARGS>
           auto operator()(ARGS&&... arg)->decltype(eval<L,R,E >(*this,std::forward<ARGS>(arg)...)) {
                return eval<L,R,E >(*this,std::forward<ARGS>(arg)...);
           }
    };

     void streamtest()
    {

        void (*foo1)(char &&)=foo;
        void (*foo2)(int ,int ,short )=foo;
        char (*foo3)()=foo;

        Pipe<char(*)(),void(*)(char&&),pipe> pp(foo3,foo1);
        pp(1);

    }

関数転送用のパイプ ライブラリを作成します。しかし、エラー混乱させてください:

 \FEstream.cpp: In function 'void streamtest()':
 \FEstream.cpp:117:9: error: no match for call to '(Pipe<char (*)(), void (*)(char&&), pipe>) (int)'
 \FEstream.cpp:98:8: note: candidate is:
 \FEstream.cpp:104:13: note: template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe]
 \FEstream.cpp:104:13: note:   template argument deduction/substitution failed:
 \FEstream.cpp: In substitution of 'template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe] [with ARGS = {int}]':
 \FEstream.cpp:117:9:   required from here
 \FEstream.cpp:104:13: error: no matching function for call to 'eval(Pipe<char (*)(), void (*)(char&&), pipe>&, int)'
 \FEstream.cpp:104:13: note: candidates are:
 \FEstream.cpp:88:6: note: template<class F, class ... ARGS> decltype (f((forward<ARGS>)(eval::arg)...)) eval(F&, ARGS&& ...)
 \FEstream.cpp:88:6: note:   template argument deduction/substitution failed:
 \FEstream.cpp:104:13: note:   cannot convert '*(Pipe<char (*)(), void (*)(char&&), pipe>*)this' (type 'Pipe<char (*)(), void (*)(char&&), pipe>') to type 'char (*&)()'
 \FEstream.cpp:93:6: note: template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(eval::arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...)
 \FEstream.cpp:93:6: note:   template argument deduction/substitution failed:
 \FEstream.cpp: In substitution of 'template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...) [with L = char (*)(); R = void (*)(char&&); E = pipe; ARGS = {int}]':
 \FEstream.cpp:104:13:   required by substitution of 'template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe] [with ARGS = {int}]'
 \FEstream.cpp:117:9:   required from here
 \FEstream.cpp:93:6: error: no matching function for call to 'eval(char (*&)(), int)'
 \FEstream.cpp:93:6: note: candidate is:
 \FEstream.cpp:88:6: note: template<class F, class ... ARGS> decltype (f((forward<ARGS>)(eval::arg)...)) eval(F&, ARGS&& ...)
 \FEstream.cpp:88:6: note:   template argument deduction/substitution failed:
 \FEstream.cpp: In substitution of 'template<class F, class ... ARGS> decltype (f((forward<ARGS>)(arg)...)) eval(F&, ARGS&& ...) [with F = char (*)(); ARGS = {int}]':
 \FEstream.cpp:93:6:   required by substitution of 'template<class L, class R, class E, class ... ARGS> decltype (Flow<E>::apply(eval(f.lhs, (forward<ARGS>)(eval::arg)...), f.rhs)) eval(Pipe<L, R, E>&, ARGS&& ...) [with L = char (*)(); R = void (*)(char&&); E = pipe; ARGS = {int}]'
 \FEstream.cpp:104:13:   required by substitution of 'template<class ... ARGS> decltype (eval<L, R, E>((* this), (forward<ARGS>)(Pipe::operator()::arg)...)) Pipe::operator()(ARGS&& ...) [with ARGS = {ARGS ...}; L = char (*)(); R = void (*)(char&&); E = pipe] [with ARGS = {int}]'
 \FEstream.cpp:117:9:   required from here
 \FEstream.cpp:88:6: error: too many arguments to function
Process terminated with status 1 (0 minutes, 0 seconds)

何が起こっているのですか?それは私のエラーですか、それとも gcc は C++11 に準拠していませんか?

/////////////////////////////////////////////// ////////////////////////////////////////

Dave S に感謝します。しかし、コードは簡略化にすぎません。実際、私は templateEval::eval を使用しています。

template<class L,class R,class E>
struct Pipe;

template<class F>
struct Eval {
     template<class...ARGS>
     static auto eval(F&f,ARGS&&... arg)->decltype(f(std::forward<ARGS>(arg)...)) {
          return f(std::forward<ARGS>(arg)...);
     }
};
template<class L,class R,class E>
struct Eval<Pipe<L,R,E> > {
     static auto eval(Pipe<L,R,E>&f)->decltype(Flow<E>::apply(f.lhs,f.rhs)) {
          return Flow<E>::apply(f.lhs,f.rhs);
     }
     template<class...ARGS>
     static void eval(Pipe<L,R,E>&f,ARGS&&...arg) {
          static_assert(!std::is_same<E,pipe>::value,
                        "multiple input for expression\nsample: auto expr=wrap(foo1)<var1|foo2 ;call expr(var2) instead of expr()");
     }
};
template<class L,class R>
struct Eval<Pipe<L,R,pipe> > {
     template<class...ARGS>
     static auto eval(Pipe<L,R,pipe>&f,ARGS&&... arg)->decltype(Flow<pipe>::apply(Eval<L>::eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs)) {
          return Flow<pipe>::apply(Eval<L>::eval(f.lhs,std::forward<ARGS>(arg)...),f.rhs);
     }
};
template<class L,class R,class E>
struct Pipe {
     L lhs;
     R rhs;
     Pipe(L &l,R& r):lhs(l),rhs(r) {
     }
  template<class...ARGS>
   auto operator()(ARGS&&... arg)->decltype(Eval<Pipe>::eval(*this,std::forward<ARGS>(arg)...)) {
        return Eval<Pipe>::eval(*this,std::forward<ARGS>(arg)...);
   }
};



         void streamtest()
        {

            void (*foo1)(char &&)=foo;
            void (*foo2)(int ,int ,short )=foo;
            char (*foo3)()=foo;

            Pipe<char(*)(),void(*)(char&&),pipe> pp(foo3,foo1);
             //pp(); //no call!
        }

エラーは次のとおりです。

  • FEstream.cpp: 'struct Eval >' のインスタンス化:
  • FEstream.cpp:121:9: 「構造体パイプ」から必要
  • FEstream.cpp:134:45: ここから必要
  • FEstream.cpp:110:18: エラー: 不完全なタイプ 'struct Pipe' の無効な使用

  • FEstream.cpp:115:8: エラー: 'struct Pipe void (*)(char&&), pipe>' の宣言

  • FEstream.cpp:110:18: エラー: 不完全なタイプ 'struct Pipe' の無効な使用
  • FEstream.cpp:115:8: エラー: 'struct Pipe void (*)(char&&), pipe>' の宣言

プロセスはステータス 1 (0 分 0 秒) で終了しました 6 エラー、0 警告

Pipe::operator()(ARGS&&... arg) はテンプレート メンバー関数です。変数 Pipe(pp) を宣言する理由 エラーが発生するのはなぜですか? 使用していないため、インスタンス化しないでくださいenter code here


誰か?そして、Pipe like で eval 関数を使うとステータスを忘れてしまう

template<class...ARGS>
   auto operator()(ARGS&&... arg)->decltype(eval(*this,std::forward<ARGS>(arg)...)) {
        return eval(*this,std::forward<ARGS>(arg)...);
   }

いいえ

 template<class...ARGS>
   auto operator()(ARGS&&... arg)->decltype(eval<L,R,E>(*this,std::forward<ARGS>(arg)...)) {
        return eval<L,R,E>(*this,std::forward<ARGS>(arg)...);
   }

reece のようなエラーが発生します: テンプレートのインスタンス化の深さが最大の 900 を超えています .....

テンプレートパラメータを指定しない場合、 eval(Pipe&f..... の代わりに Eval(F&.... を選択するようです

4

2 に答える 2

2

呼び出しチェーンのどこかで、引数の不一致が原因で問題が発生しています。そのため、問題を見つけるために手動で行うことができます。

Pipe<char(*)(),void(*)(char&&),pipe> pp(foo3,foo1);として 0 引数を取る foo3 と、 としてLchar 右辺値参照を取る foo1 を使用していRます。そしてE、あなたのマーカー構造はpipe

int 1 で呼び出した場合。

pp(1)を呼び出しeval<L,R,E>(*this, 1)、次に呼び出します

Flow<E>::apply(eval(foo3,1),foo1).

まず、内部評価が呼び出されます。これは の declval を判別しようとしますfoo3(1)が、foo3 は 0 の引数を取るように宣言されています。これにより、コンパイル エラーが発生し、その結果、置換エラーが発生します。

編集:変更された質問により、問題はEvalforの特殊化を作成していることですPipeが、(decltype を介して) return 宣言でEvalフィールドを使用しようとしており、同じことを行っています。最初に何かを定義できるようにそのサイクルを壊すか、少なくとも関数宣言でサイクルが導入されないように設定して、両方の型を完全に定義した後にメソッドを定義できるようにする必要があります。 .PipePipe

Evalクラスが何を達成しようとしているのかわからない。1 つの解決策は、それを完全に削除してPipe::operator()、メソッドをより直接的に呼び出すことです。

于 2012-08-06T13:35:12.603 に答える
0
于 2012-08-06T13:57:41.410 に答える