3

テンプレート関数にコールバックを渡そうとしていますが、GCC は私に

error: no matching function for call to ‘Test::iterate(main(int, char**)::<anonymous struct>&)’

なぜこれが機能しないのですか?(また、やむを得ない理由により、C++11 を使用できません。)

また、構造体に名前を付けて egmyvisを呼び出してみましtest.iterate<myvis>(visitor)たが、それもうまくいきませんでした。

#include <deque>
#include <iostream>

class Test {
public:
    std::deque<int> d;

    template <typename C>
    void iterate(C& c) {
        for(std::deque<int>::iterator itr = d.begin(); itr != d.end(); itr++) {
            c(*itr);
        }
    }
};

int main(int argc, char** argv) {
    Test test;
    test.d.push_back(1);
    test.d.push_back(2);
    struct {
        void operator()(int x) {
            std::cout << x << std::endl;
        }
    } visitor;
    test.iterate(visitor);
}
4

3 に答える 3

3

C++03 標準では、§14.3.1.2 [temp.arg.type] で次のように述べています。

ローカル型、リンケージのない型、名前のない型、またはこれらの型のいずれかを組み合わせた型は、テンプレート型パラメーターのテンプレート引数として使用してはなりません。

したがって、ローカルの名前のない構造体ではなく、グローバルな名前の構造体が必要で、次のようなものが得られます。

struct Visitor {
    void operator()(int x) {
        std::cout << x << std::endl;
    }
} visitor;
int main(int argc, char** argv) {
    Test test;
    test.d.push_back(1);
    test.d.push_back(2);
    Visitor visitor;
    test.iterate(visitor);
}

local/unnamed typed の制限は c++11 で解除されているため、使用しない理由がいつか解消されれば、コードはそのままで問題ありません。

于 2012-08-20T21:06:53.717 に答える
1

visitorグローバルにすることもできますし、 のstructように名前を付ける必要もありますVisitor

#include <deque>
#include <iostream>

struct Visitor {
    void operator()(int x) 
    {
       std::cout << x << std::endl;
    }
};


class Test {
public:
    std::deque<int> d;

    template <typename C>
    void iterate(C& c) {
        for(std::deque<int>::iterator itr = d.begin(); itr != d.end(); itr++) {
            c(*itr);
        }
    }
};

int main(int argc, char** argv) {
    Test test;
    test.d.push_back(1);
    test.d.push_back(2);
    Visitor visitor;
    test.iterate(visitor);
}
于 2012-08-20T21:17:53.427 に答える
1

2 つのエラーがあります。

まず、ローカル型visitorを使用してテンプレート メンバー関数関数をインスタンス化することはできませんiterate(これは C++11 で機能します)。

第 2 に、ここで匿名型を使用することはできません。名前付きが必要であり、struct visitorそのインスタンスを渡す必要があります。

#include <deque>
#include <iostream>

struct visitor {
  void operator()(int x) {
    std::cout << x << std::endl;
  }
};

class Test {
public:
  std::deque<int> d;

  template <typename C>
  void iterate(C& c) {
    for(std::deque<int>::iterator itr = d.begin(); itr != d.end(); itr++) {
      c(*itr);
    }
  }
};

int main() {
  Test test;
  test.d.push_back(1);
  test.d.push_back(2);

  visitor v;
  test.iterate(v);
}
于 2012-08-20T21:13:23.453 に答える