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);
}

在 c++11 中取消了对本地/未命名类型的限制,所以如果那些不使用它的原因有一天会消失,那么你的代码会保持原样。

于 2012-08-20T21:06:53.717 回答
1

你有两个错误。

首先,您不能使用本地类型visitor来实例化模板成员函数函数iterate(这将在 C++11 中工作)。

其次,这里不能有匿名类型。你需要一个命名的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 回答
1

您可以使visitorglobal 并且您还需要命名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 回答