C模板过度使用
我已经把我遇到的模板专业化使用的两个代码摘录放在一起,我觉得特别奇怪.我甚至会不必要地称他们浮华.
总的来说,我怀疑模板实际上是设计这些对象的最佳方式(尤其是第一种情况). 哪种方法更好,为什么?或者是否有一种完全不同的方法更好? 1)模板作为函数传递指针的替代: //fusion_manager.h template <typename InputFilterAlgorithm,typename PredictionAlgorithm,typename AssociationAlgorithm,typename FusionAlgorithm> class FusionManager { public: FusionManager(Environment& env); ... private: Environment& env_m; InputFilterAlgorithm filter_alg_m; PredictionAlgorithm prediction_alg_m; AssociationAlgorithm association_alg_m; FusionAlgorithm fusion_alg_m; ... }; //fusion_manager.cpp template <typename InputFilterAlgorithm,typename FusionAlgorithm> FusionManager<InputFilterAlgorithm,PredictionAlgorithm,AssociationAlgorithm,FusionAlgorithm,TrackExtendedDataType>::FusionManager(Environment& env) : env_m(env),filter_alg_m(env),prediction_alg_m(env),association_alg_m(env),fusion_alg_m(env) { ... } //main.cpp ... FusionManager<TestInputFilterAlgorithm,TestPredictionAlgorithm,TestAssociationAlgorithm,TestFusionAlgorithm> fusionManager(env); ... ……而不是使用这样的东西: //fusion_manager.h class FusionManager { public: ??//Let's say each algorithm is encapsulated by a class ??FusionManager(Environment& env,??????????InputFilterAlgorithm&&,?????????? ??????PredictionAlgorithm&&,?????????? ??????AssociationAlgorithm&&,?????????? ??????FusionAlgorithm&&); private: ??Environment& env_m; ????InputFilterAlgorithm filter_alg_m; ????PredictionAlgorithm prediction_alg_m; ????AssociationAlgorithm association_alg_m; ????FusionAlgorithm fusion_alg_m; }; //fusion_manager.cpp FusionManager::FusionManager(Environment& env,???????????????????? InputFilterAlgorithm&& filter_alg,???????????????????? PredictionAlgorithm&& prediction_alg,???????????????????? AssociationAlgorithm&& association_alg,???????????????????? FusionAlgorithm&& fusion_alg) ??????????: ??????????????env_m(env),??????????????filter_alg_m(std::move(filter_alg)),??????????????prediction_alg_m(std::move(prediction_alg)),??????????????association_alg_m(std::move(association_alg)),??????????????fusion_alg_m(std::move(fusion_alg)) { ??... } //main.cpp ... FusionManager<TestInputFilterAlgorithm,????????????TestPredictionAlgorithm,????????????TestAssociationAlgorithm,????????????TestFusionAlgorithm> fusionManager(env); ... 2)使用模板替代继承和虚拟方法: //factorization.h template<typename ProbabilityDistributionType> class Factorization { ... public: ProbabilityDistributionType factorize(); private: std::Vector<ProbabilityDistributionType> factors_m; ... }; //factorization.cpp template<> CPD Factorization<CPD>::factorize() { for (auto & factor : factors_m) { factor.factorize();//This will call the factorize method of CPD } } template<> JointProbDistr Factorization<JointProbDistr>::factorize() { for (auto & factor : factors_m) { factor.factorize();//This will call the factorize method of JointProbDistr } } 而不是使用这样的东西: //factorization.h template<typename ProbabilityDistributionType> class Factorization { ... public: virtual ProbabilityDistributionType factorize() = 0; private: std::Vector<ProbabilityDistributionType> factors_m; ... }; //cpd_factorization.h class CPDFactorization : public Factorization<CPD> { ... public: CPD factorize();//Implementing the parent's pure virtual method. This will call the factorize method of CPD }; //jointprobdistr_factorization.h class CPDFactorization : public Factorization<JointProbDistr> { ... public: JointProbDistr factorize();//Implementing the parent's pure virtual method. This will call the factorize method of JointProbDistr }; 解决方法
使用模板既有优点也有缺点,编译器可以看到使用模板的完全专用的实现.
这是一个优势,因为它允许编译器更积极地进行优化:它可以根据需要内联,并解决函数调用之间的任何数据移位,消除程序员为了构建而可能引入的所有错误他们的源代码方便. 这是一个缺点,因为它迫使模板化决策成为编译时决策.如果变量是模板参数,则它不能依赖于在运行时给出的输入.想象一下,如果std :: string的长度是模板参数会发生什么:字符串操作与FORTRAN一样灵活.你绝对不希望这样.当然,有些事情应该在编译时知道,并且将它们作为模板参数是非常好的.但是如果你过度使用模板,就会得到不必要的严格代码. (在那里,完成了,学会了避免它.) 这也是一个缺点,因为它强制在实现更改时重新编译模板的所有用法.如果你的程序是除main之外的所有模板,你必须为每一个小的改动重新编译所有的东西.如果使用指向函数,虚函数和/或仿函数的指针,则在调用函数的实现发生更改时,不需要重新编译调用站点.在正确设置的构建系统中,它们将依赖于标题,除非有破坏的接口更改,否则标题不会更改.对我来说,其结果是,我的所有模板都应该是小的,自包含的代码,不依赖于多个层中的其他模板. 总而言之,模板是一个很好的工具,同时也是一个非常容易被滥用的工具.当你没有从中获得任何真正的优势时,尽量不要使用它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |