在构建时指定模板参数

时间:2018-03-21 16:05:51

标签: c++ templates

我已经使用模板来实现路径策略。

#include <fstream>
#include <DefaultPolicy.h>

template<typename PathPolicy = DefaultPolicy>
class FileReader
{
    public:
    double getNextNumber();

    private:
    PathPolicy pp;
    readNumbers() { std::ifstream myFile(pp.path); }; //And so on
 };

我实施了:

[HEADER]
struct DefaultPolicy
{
   public:
   std::string path
   DefaultPolicy()
} ;

[IMPLEMENTATION]
DefaultPolicy::DefaultPolicy() : path("."){}

所以现在我想实施许多不同的政策,如:

[HEADER]
struct UnitTestPolicy
{
   public:
   std::string path
   UnitTestPolicy()
} ;

[IMPLEMENTATION]
UnitTestPolicy::UnitTestPolicy() : path("unittests/resources"){}

[HEADER]
struct OperationalPathPolicy
{
   public:
   std::string path
   OperationalPathPolicy()
} ;

[IMPLEMENTATION]
OperationalPathPolicy::OperationalPathPolicy() : path("/sw/cm/resources"){}

我不确定如何切换我的政策。这些是编译时选择,我可以选择我正在构建的目标,但我唯一的想法是回退到宏来进行选择。如果我这样做,那么我真的不需要政策的模板抽象。

我应该如何在构建时选择策略类?

2 个答案:

答案 0 :(得分:4)

  

但我唯一的想法是回到宏来做出选择

真。

  

如果我这样做,那么我真的不需要政策的模板抽象。

假。模板抽象可以帮助您最大限度地减少预处理器的使用,并彻底隔离您的策略。

您还可以强制在.cpp文件中实例化模板类,以避免模板导致的编译时开销,因为您了解所有可能的策略类型。

// filereaderimpl.hpp

namespace detail 
{ 
    template<typename PathPolicy>
    class FileReaderImpl { /* ... */ };
}

// filereader.hpp
#include <fileheaderimpl.hpp>

#ifdef SOME_BUILD_TIME_CHOICE
using FileReader = detail::FileHeaderImpl<SomePolicy>;
#else
using FileReader = detail::FileHeaderImpl<SomeOtherPolicy>;
#endif

答案 1 :(得分:0)

编辑:我误解了问题,下面的解决方案将允许在运行时选择策略,您要求在构建时选择。

我认为继承可以更好地解决您的问题。

所以你有一个基础PathPolicy(你可以称它为DefaultPolicy)类,然后让其他策略继承自PathPolicy类。

所以你的UnitTestPolicy变成了

struct UnitTestPolicy : public PathPolicy
{
   public:
     UnitTestPolicy()
     {
       path = "blah//blah";
     }
} ;

然后在文件阅读器中,仅使用基类来抽象策略类的其他实现。这样你的文件阅读器就不关心政策是什么了;它只是要读取文件。

工作示例here