将模板化对象存储在容器中

发布于 2024-09-28 00:32:04 字数 3806 浏览 0 评论 0 原文

是否可以

template <typename rtn, typename arg>
class BufferAccessor {
  public:
    int ThreadID;
    virtual rtn do_work(arg) = 0;  
}; 

BufferAccessor<void,int> access1;
BufferAccessor<int,void> access2;

像矢量或列表

编辑一样将模板化类存储在同一个容器中: 这样做的目的是我试图创建一个循环缓冲区,其中想要使用缓冲区的对象需要向缓冲区注册。缓冲区将存储一个 boost::shared_ptr 到访问器对象,并生成一个回调函数,将数据推送到缓冲区或从缓冲区提取数据。该回调将在我创建的类似于线程池的通用线程工作函数中使用,事实上它们需要访问共享内存对象。下面是我输入的一些代码,可能有助于说明我正在尝试做的事情,但它尚未编译,这也是我第一次使用绑定、函数、多线程

 typedef boost::function<BUF_QObj (void)> CallbackT_pro;
        typedef boost::function<void (BUF_QObj)> CallbackT_con;
        typedef boost::shared_ptr<BufferAccessor> buf_ptr;

        // Register the worker object
            int register_consumer(BufferAccesser &accessor) {
                mRegCons[mNumConsumers] = buf_ptr(accessor);
                return ++mNumConsumers;
            }

            int register_producer(BufferAccesser &accessor) {
                mRegPros[mNumProducers] = buf_ptr(accessor);
                return ++mNumProducers;
            }
                // Dispatch consumer threads
                for(;x<mNumConsumers; ++x) {
                    CallBack_Tcon callback_con = boost::bind(&BufferAccessor::do_work, mRegCons[x]);
                    tw = new boost:thread(boost::bind(&RT_ActiveCircularBuffer::consumerWorker, this, callback_con));
                    consumers.add(tw);
                }

                // Dispatch producer threads
                for(x=0;x<mNumProducers; ++x) {
                    CallBack_Tpro callback_pro = boost::bind(&BufferAccessor::do_work, mRegPros[x], _1);
                    tw = new boost:thread(boost::bind(&RT_ActiveCircularBuffer::producerWorker, this, callback_pro));
                    producers.add(tw);
                }
        // Thread Template Workers - Consumer
            void consumerWorker(CallbackT_con worker) {
                struct BUF_QObj *qData;

                while(!mRun)
                    cond.wait(mLock);

                while(!mTerminate) {
                    // Set interruption point so that thread can be interrupted
                    boost::thread::interruption_point();
                    { // Code Block
                        boost::mutex::scoped_lock lock(mLock);
                        if(buf.empty()) {
                            cond.wait(mLock)

                        qData = mBuf.front();
                        mBuf.pop_front(); // remove the front element
                    } // End Code Block

                    worker(qData); // Process data

                    // Sleep that thread for 1 uSec
                    boost::thread::sleep(boost::posix_time::nanoseconds(1000));
                } // End of while loop
            }

            // Thread Template Workers - Producer
            void producerWorker(CallbackT_pro worker) {
                struct BUF_QObj *qData;
                boost::thread::sleep(boost::posix_time::nanoseconds(1000));

                while(!mRun)
                    cond.wait(mLock);

                while(!mTerminate) {
                    // Set interruption point so that thread can be interrupted
                    boost::thread::interruption_point();

                    qData = worker(); // get data to be processed

                    { // Code Block
                        boost::mutex::scoped_lock lock(mLock);
                        buf.push_back(qData);
                        cond.notify_one(mLock);
                    } // End Code Block

                    // Sleep that thread for 1 uSec
                    boost::thread::sleep(boost::posix_time::nanoseconds(1000));
                } // End of while loop
            }

Is it possible to store a templated class like

template <typename rtn, typename arg>
class BufferAccessor {
  public:
    int ThreadID;
    virtual rtn do_work(arg) = 0;  
}; 

BufferAccessor<void,int> access1;
BufferAccessor<int,void> access2;

in the same container like a vector or list

edit:
The purpose for this is I am trying to make a circular buffer where the objects that want to use the buffer need to register with the buffer. The buffer will store a boost::shared_ptr to the accessor objects and generate a callback to there functions that will push or pull data to/from the buffer. The callback will be used in a generic thread worker function that I have created similar to a thread pool with the fact that they need to access a shared memory object. Below is some code I have typed up that might help illustrate what I am trying to do, but it hasn't been compiled it yet and this is also my first time using bind, function, multi-threading

 typedef boost::function<BUF_QObj (void)> CallbackT_pro;
        typedef boost::function<void (BUF_QObj)> CallbackT_con;
        typedef boost::shared_ptr<BufferAccessor> buf_ptr;

        // Register the worker object
            int register_consumer(BufferAccesser &accessor) {
                mRegCons[mNumConsumers] = buf_ptr(accessor);
                return ++mNumConsumers;
            }

            int register_producer(BufferAccesser &accessor) {
                mRegPros[mNumProducers] = buf_ptr(accessor);
                return ++mNumProducers;
            }
                // Dispatch consumer threads
                for(;x<mNumConsumers; ++x) {
                    CallBack_Tcon callback_con = boost::bind(&BufferAccessor::do_work, mRegCons[x]);
                    tw = new boost:thread(boost::bind(&RT_ActiveCircularBuffer::consumerWorker, this, callback_con));
                    consumers.add(tw);
                }

                // Dispatch producer threads
                for(x=0;x<mNumProducers; ++x) {
                    CallBack_Tpro callback_pro = boost::bind(&BufferAccessor::do_work, mRegPros[x], _1);
                    tw = new boost:thread(boost::bind(&RT_ActiveCircularBuffer::producerWorker, this, callback_pro));
                    producers.add(tw);
                }
        // Thread Template Workers - Consumer
            void consumerWorker(CallbackT_con worker) {
                struct BUF_QObj *qData;

                while(!mRun)
                    cond.wait(mLock);

                while(!mTerminate) {
                    // Set interruption point so that thread can be interrupted
                    boost::thread::interruption_point();
                    { // Code Block
                        boost::mutex::scoped_lock lock(mLock);
                        if(buf.empty()) {
                            cond.wait(mLock)

                        qData = mBuf.front();
                        mBuf.pop_front(); // remove the front element
                    } // End Code Block

                    worker(qData); // Process data

                    // Sleep that thread for 1 uSec
                    boost::thread::sleep(boost::posix_time::nanoseconds(1000));
                } // End of while loop
            }

            // Thread Template Workers - Producer
            void producerWorker(CallbackT_pro worker) {
                struct BUF_QObj *qData;
                boost::thread::sleep(boost::posix_time::nanoseconds(1000));

                while(!mRun)
                    cond.wait(mLock);

                while(!mTerminate) {
                    // Set interruption point so that thread can be interrupted
                    boost::thread::interruption_point();

                    qData = worker(); // get data to be processed

                    { // Code Block
                        boost::mutex::scoped_lock lock(mLock);
                        buf.push_back(qData);
                        cond.notify_one(mLock);
                    } // End Code Block

                    // Sleep that thread for 1 uSec
                    boost::thread::sleep(boost::posix_time::nanoseconds(1000));
                } // End of while loop
            }

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

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

发布评论

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

评论(2

腹黑女流氓 2024-10-05 00:32:04

不,不是,因为 STL 容器是同质的,access1 和 access2 具有完全不同的不相关类型。但是您可以将 BufferAccessor 类设为非模板类​​,而将 do-work 成员设为模板,如下所示:

class BufferAccessor
{
   template<class R, class A>
   R doWork(A arg) {...}
};

在这种情况下,您可以将 BufferAccessors 存储在容器中,但不能将成员模板函数设为虚拟。

No it's not, because STL containers are homogenous, and access1 and access2 have completely different unrelated types. But you could make the class BufferAccessor non-template one but the do-work member as a template, like this:

class BufferAccessor
{
   template<class R, class A>
   R doWork(A arg) {...}
};

In this case you could store BufferAccessors in a container, but you can't make a member template function virtual.

葮薆情 2024-10-05 00:32:04

是的,您可以使用 vector; > 存储 BufferAccessor 对象和 vector 对象> 存储 BufferAccessor 对象。

您不能做的是使用相同的向量来存储 BufferAccessorBufferAccessor 对象
它不起作用的原因是因为 BufferAccessorBufferAccessor 是两个不同的类

注意:它是可以使用相同的向量来存储 BufferAccessorBufferAccessor 但您必须将它们存储为 void *< /code> 使用 shared_ptr。或者更好的是,您可以使用 boost::variant

Yes, you can use vector<BufferAccessor<void,int> > to store BufferAccessor<void,int> objects and vector<BufferAccessor<int,void> > to store BufferAccessor<int,void> objects.

What you cant do is use same vector to store both BufferAccessor<int,void> and BufferAccessor<void,int> object
The reason it doesnt work is because BufferAccessor<void,int>, and BufferAccessor<int,void> are two different classes

Note: it is possible to use same vector to store both BufferAccessor<int,void> and BufferAccessor<void,int> but you would have to either store them as void * using shared_ptr<void>. Or better yet you can use a boost::variant

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