接受回调的模板功能的“无匹配功能”

时间:2012-08-20 20:56:29

标签: c++ templates

我正在尝试将回调传递给模板函数,但是GCC给了我

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

为什么这不起作用? (另外,由于我无法控制的原因,我无法使用C ++ 11.)

我也试过命名结构,例如myvis并致电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);
}

3 个答案:

答案 0 :(得分: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中取消了对本地/未命名类型的限制,所以如果不使用它的原因有一天会消失,你的代码就会没问题。

答案 1 :(得分: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);
}

答案 2 :(得分: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);
}