增强绑定功能

发布于 2024-08-28 07:15:37 字数 736 浏览 5 评论 0原文

我有一个抽象基类 A 和一组 10 个派生类。中缀运算符在所有派生类中都被重载。

class A{
 public:
    void printNode( std::ostream& os )
    {
           this->printNode_p();
    } 
  protected:
    virtual void printNode_p( std::ostream& os )
    {
           os << (*this);
    }
};

有一个存储基类指针的容器。我想使用 boost::bind 函数来调用其每个派生类中的重载中缀运算符。我是这样写的,

std::vector<A*> m_args
....
std::ostream os;
for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, os) );

这段代码有什么问题吗?在 Visual Studio 中我收到这样的错误

错误 C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : 无法访问私有成员 在课堂上声明 'std::basic_ios<_Elem,_Traits>'

谢谢, 戈库尔。

I have a abstract base class A and a set of 10 derived classes. The infix operator is overloaded in all of the derived classes

class A{
 public:
    void printNode( std::ostream& os )
    {
           this->printNode_p();
    } 
  protected:
    virtual void printNode_p( std::ostream& os )
    {
           os << (*this);
    }
};

There is a container which stores the base class pointers. I want to use boost::bind function to call the overloaded infix operator in each of its derived class. I have written like this

std::vector<A*> m_args
....
std::ostream os;
for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, os) );

What is the problem with this code? In visual studio i am getting an error like this

error C2248:
'std::basic_ios<_Elem,_Traits>::basic_ios'
: cannot access private member
declared in class
'std::basic_ios<_Elem,_Traits>'

Thanks,
Gokul.

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

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

发布评论

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

评论(2

旧伤还要旧人安 2024-09-04 07:15:37

考虑一下,它按预期工作:

#include <iostream>

struct base
{
    virtual ~base(void) {}

    virtual void print(std::ostream& pStream) = 0;
};

struct foo : base
{
    void print(std::ostream& pStream) { pStream << "foo" << std::endl; }
};

struct bar : base
{
    void print(std::ostream& pStream) { pStream << "bar" << std::endl; }
};

#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <algorithm>

int main(void)
{
    boost::ptr_vector<base> v;
    v.push_back(new foo);
    v.push_back(new bar);

    std::for_each(v.begin(), v.end(),
                  boost::bind(&base::print, _1, boost::ref(std::cout)));
}

首先,由于您使用的是 boost,您也可以使用 ptr_vector 来为您处理内存管理。所以,那就在那里。

其次,您的错误是因为流不可复制;但是,boost::bind 会在构造函子时复制所有参数。将其包装在可复制的 boost::reference_wrapper 中(使用 boost::ref 实用函数)。当时机成熟时,包装器将转换为必要的类型,您不会注意到其中的差异。

(这是 boost::ref 的用途之一。)


总而言之,请考虑使用 BOOST_FOREACH,在我看来,它会生成最干净的代码:

#include <boost/foreach.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <algorithm>

#define foreach BOOST_FOREACH

int main(void)
{
    boost::ptr_vector<base> v;
    v.push_back(new foo);
    v.push_back(new bar);

    foreach (base* b, v)
    {
        v->print(std::cout);
    }
}

Consider this, which works as expected:

#include <iostream>

struct base
{
    virtual ~base(void) {}

    virtual void print(std::ostream& pStream) = 0;
};

struct foo : base
{
    void print(std::ostream& pStream) { pStream << "foo" << std::endl; }
};

struct bar : base
{
    void print(std::ostream& pStream) { pStream << "bar" << std::endl; }
};

#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <algorithm>

int main(void)
{
    boost::ptr_vector<base> v;
    v.push_back(new foo);
    v.push_back(new bar);

    std::for_each(v.begin(), v.end(),
                  boost::bind(&base::print, _1, boost::ref(std::cout)));
}

First off, since you're using boost you may as well use ptr_vector to handle memory management for you. So, that's in there.

Secondly, your error is because streams are not copyable; however, boost::bind will make a copy of all it's arguments when constructing the functor. Wrap it in a boost::reference_wrapper (using the boost::ref utility function), which is copyable. When the time comes, the wrapper will convert to the necessary type and you won't notice the difference.

(This is one of the situations boost::ref was made for.)


That all said, consider using BOOST_FOREACH, which in my opinion generates the cleanest code:

#include <boost/foreach.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <algorithm>

#define foreach BOOST_FOREACH

int main(void)
{
    boost::ptr_vector<base> v;
    v.push_back(new foo);
    v.push_back(new bar);

    foreach (base* b, v)
    {
        v->print(std::cout);
    }
}
月隐月明月朦胧 2024-09-04 07:15:37

问题是 std::ostream 不可复制。我像这样修复了

for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, boost::ref(os) ) );

谢谢,
戈库尔。

The problem was that std::ostream is not copyable. I fixed it like this

for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, boost::ref(os) ) );

Thanks,
Gokul.

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