C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 将模板对象存储为成员对象大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
假设你有一些这样的代码
struct Manager
{
  template <class T> 
  void doSomething(T const& t)
  {
    Worker<T> worker;
    worker.work(t);
  }
};

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

@H_106_2@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 – 将模板对象存储为成员对象所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。