mem_func 和虚函数

发布于 2024-10-09 02:36:43 字数 561 浏览 0 评论 0原文

我有以下课程:

 class A
{
   public:
        virtual void myfunc(unsigned char c, std::string* dest) = 0;
};

   class B : public class A
{
    public:
        virtual void myfunc(unsigned char c, std::string* dest);
};

void someOtherFunc(const std::string& str,A *pointerFunc)
{
    std::string tmp;
        for_each(str.begin(),
                 str.end(),                 
                 std::bind2nd(std::mem_fun(pointerFunc->myfunc), &tmp));
}

我收到以下编译错误: 错误:没有匹配的函数来调用 \u2018mem_fun()\u2019

你知道为什么吗?

I have the following classes:

 class A
{
   public:
        virtual void myfunc(unsigned char c, std::string* dest) = 0;
};

   class B : public class A
{
    public:
        virtual void myfunc(unsigned char c, std::string* dest);
};

void someOtherFunc(const std::string& str,A *pointerFunc)
{
    std::string tmp;
        for_each(str.begin(),
                 str.end(),                 
                 std::bind2nd(std::mem_fun(pointerFunc->myfunc), &tmp));
}

I get the following compilation error:
error: no matching function for call to \u2018mem_fun()\u2019

Do you know why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

掀纱窥君容 2024-10-16 02:36:43

您正在寻找 std::mem_fun(&A::myfunc)

编辑:您在这里根本无法使用 mem_fun -- 没有重载 mem_fun 允许您将两个参数的成员函数变成函子。您将必须使用类似 boost::bind/std::tr1::bind (如果您有 TR1)/std::bind (如果您有 C++0x)或者您将不得不编写自己的函子。

请注意,即使 mem_fun 能够执行这种绑定,std::bind2nd 也会失败,因为 bind2nd 期望函子需要两个参数,并像这样绑定成员函数指针将生成一个具有三个参数的函子。

您有几种方法可以解决此问题:

  1. 编写自己的函子来执行您想要的操作。
  2. 编写一个显式循环而不是 std::for_each
  3. 我上面提到的一个尚未标准的绑定器函数(并在@David的回答中演示)
  4. 首先不要为虚拟函数烦恼——让你的方法接受一个简单的函数指针并根据函数指针。当然,这仅在 myfunc 不依赖于其所属类的成员的情况下才有效(在这种情况下,它一开始就不应该被放入类中)

You're looking for std::mem_fun(&A::myfunc).

EDIT: You can't use mem_fun at all here -- no overload of mem_fun allows you to make a two argument member function into a functor. You're going to have to use something like boost::bind/std::tr1::bind (If you have TR1)/std::bind (If you have C++0x) or you're going to have to write your own functor.

Note that even if mem_fun was able to do this sort of binding, then std::bind2nd would fail, because bind2nd expects a functor taking two arguments, and binding a member function pointer like this is going to produce a functor with three arguments.

You have a few ways around this:

  1. Write your own functor that does what you want.
  2. Write an explicit loop instead of std::for_each.
  3. One of the not-yet-standard binder functions I mentioned above (and demonstrated in @David's answer)
  4. Don't bother with the virtual function in the first place -- make your method accept a plain function pointer and implement things in terms of the function pointer. Of course this only works if myfunc doesn't depend on members of the class to which it belongs (in which case it shouldn't have ever been put into a class in the first place)
永不分离 2024-10-16 02:36:43

您在这里尝试使用的是使用指向成员函数的指针来应用容器中每个对象的另一个对象的成员函数。显然,在这种情况下,任何适配器都不起作用。在这种情况下,唯一的解决方案是为其编写一个特殊的包装函子类。

What you are trying to use here is use a pointer to a member function to apply a member function of another object to every object in the container. Apparently none of the adapters will work in this case. In that case the only solution is to write a special wrapper functor class for it.

旧人 2024-10-16 02:36:43

查看 std::mem_fun 背后的实现,您应该能够编写自己的:

编辑(使其“人类可读”)

template<class Result, class Ty, class Arg>
class mem_fun1_t : public binary_function<Ty*, Arg, Result>
{
private:
 Result (Ty::*m_mf)(Arg);

public:
 mem_fun1_t(Result (Ty::*mf)(Arg)) : m_mf(mf) { }

 Result operator()(Ty* pLeft, Arg Right) const {
  return ((pLleft->*m_mf)(Right));
 }
};

Looking at the implementation behind of std::mem_fun you should be able to write your own:

EDIT (made it "human-readable")

template<class Result, class Ty, class Arg>
class mem_fun1_t : public binary_function<Ty*, Arg, Result>
{
private:
 Result (Ty::*m_mf)(Arg);

public:
 mem_fun1_t(Result (Ty::*mf)(Arg)) : m_mf(mf) { }

 Result operator()(Ty* pLeft, Arg Right) const {
  return ((pLleft->*m_mf)(Right));
 }
};
半世蒼涼 2024-10-16 02:36:43

您的声明并不代表您想要做什么。

尝试:

void someOtherFunc(const std::string& str)
{
    std::string tmp;

    B BInstance;
    A* ptrToB = &BInstance;


    for_each(str.begin(),
        str.end(),                 
        boost::bind(&A::myfunc, ptrToB, _1, &tmp));
}

这个(或其变体)应该可以满足您的需求。

Your declaration does not represent what you want to do.

try:

void someOtherFunc(const std::string& str)
{
    std::string tmp;

    B BInstance;
    A* ptrToB = &BInstance;


    for_each(str.begin(),
        str.end(),                 
        boost::bind(&A::myfunc, ptrToB, _1, &tmp));
}

this (or a variation of) should do what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文