c – 将模板对象存储为成员对象

c – 将模板对象存储为成员对象,第1张

概述假设你有一些这样的代码: struct Manager{ template <class T> void doSomething(T const& t) { Worker<T> worker; worker.work(t); }}; 一个“管理器”对象被创建一次,并使用一些不同类型“T”进行调用,但每个类型T被调用多次.这可能是一个简化的形式 Manager 假设你有一些这样的代码:
struct Manager{  template <class T>   voID doSomething(T const& t)  {    Worker<T> worker;    worker.work(t);  }};

一个“管理器”对象被创建一次,并使用一些不同类型“T”进行调用,但每个类型T被调用多次.这可能是一个简化的形式

Manager manager;const int N = 1000;for (int i=0;i<N;i++){  manager.doSomething<int>(3);  manager.doSomething<char>('x');  manager.doSomething<float>(3.14);}

现在,剖析表明,构建一个“工人”是一个耗时的 *** 作,应该避免构造它N次(在doSomething< T>)内.为了线程安全的原因,可以有一个Worker< int>,一个Worker< char>和< float>每个“经理”,但不是一个工作者< int>为所有经理.所以通常我会使“worker”成员变量.但是我该如何在上面的代码中做到这一点? (我事先不知道会使用“T”).

我已经找到了一个使用std :: map的解决方案,但它并不完全是类型安全的,当然不太优雅.你可以建议一种类型安全的方式,而不需要构建“工作人员”没有虚拟方法,每“T”多一次?

(请注意,Worker不是源自任何模板参数的免费基类).

谢谢任何解决方案!

解决方法 您可以使用类似std :: map< std :: type_info,shared_ptr< voID> >喜欢这个:
#include <map>#include <typeinfo>#include <utility>#include <functional>#include <boost/shared_ptr.hpp>using namespace std;using namespace boost;// exposition only:template <typename T>struct Worker {    voID work( const T & ) {}};// wrapper around type_info (Could use reference_wrapper,// but the code would be similar) to make it usable as a map<> key:struct TypeInfo {    const type_info & ti;    /*implicit*/ TypeInfo( const type_info & ti ) : ti( ti ) {}};// make it LessComparable (Could spcialise std::less,too):bool operator<( const TypeInfo & lhs,const TypeInfo & rhs ) {    return lhs.ti.before( rhs.ti );}struct Manager{    map<TypeInfo,shared_ptr<voID> > m_workers;    template <class T>     Worker<T> * finDWorker()    {        const map<TypeInfo,shared_ptr<voID> >::const_iterator        it = m_workers.find( typeID(T) );        if ( it == m_workers.end() ) {            const shared_ptr< Worker<T> > nworker( new Worker<T> );            m_workers[typeID(T)] = nworker;            return nworker.get();        } else {            return static_cast<Worker<T>*>( it->second.get() );        }    }    template <typename T>    voID doSomething( const T & t ) {        finDWorker<T>()->work( t );    }};int main() {    Manager m;    m.doSomething( 1 );    m.doSomething( 1. );    return 0;}

这是类型安全的,因为我们使用type_info作为地图中的索引.而且,即使它们在shared_ptr< voID>中,工作者也被正确删除,因为删除者是从原始的shared_ptr< Worker< T>并且那个调用正确的构造函数.它也不使用虚拟函数,虽然所有类型的擦除(和这是一个)在某处使用类似虚拟函数.这里是shared_ptr.

将来自finDWorker的与模板无关的代码转换为非模板函数以减少代码膨胀留给读者的练习:)

感谢所有评论者指出使用type_info作为键的错误.

总结

以上是内存溢出为你收集整理的c – 将模板对象存储为成员对象全部内容,希望文章能够帮你解决c – 将模板对象存储为成员对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1252489.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存