2016-11-28 63 views
1

我已经看到了在运行时动态地选择变量类型(thisthis以及从那里的链接)的答案,但即使有些可能会稍微过时我的头(对C++来说相当新颖),有没有办法从配置文件中读取变量类型并在运行时使用它?通过配置文件在运行时选择变量类型

例如,配置可能有type=double作为一行,并且可以通过程序的设置更改为type=long double,并在不重新启动应用程序的情况下使用该变量类型。


我需要计算一些多项式的根。有的甚至是小订单,需要很高的精度,如果达到高订单,他们需要更大的订单。尽管如此,我仍然可以用doublelong double来取代足够小的数字,但是当我变得更高时,我需要MPFRC++(这就是我现在唱的)。我希望避免放慢速度(即使小订单不太明显),只有在需要时才能使用高精度。

+2

简单的回答:编号 – NathanOliver

+1

在编译时确定并实例化C++程序中使用的所有变量类型。也许你可以链接一些这些答案,我们可以解释那里做了什么。 –

+0

也许你可以使用if else else if(type ==“double”)double var;否则,如果..... – Sniper

回答

2

你可能会使用的是Factory Pattern以及Strategy Pattern和一个合适的接口。沿着线的东西:

struct IPolyRootSolver { 
    virtual PolyRoot calcRoot(const Polynom& poly) const = 0; 
    virtual ~IPolyRootSolver() {} 
}; 

class DoublePolyRootSolver : public IPolyRootSolver { 
public: 
    PolyRoot calcRoot(const Polynom& poly) { 
     // Implementation based on double precision 
    } 
}; 

class LongDoublePolyRootSolver : public IPolyRootSolver { 
public: 
    PolyRoot calcRoot(const Polynom& poly) { 
     // Implementation based on long double precision 
    } 
}; 

class MPFRCPolyRootSolver : public IPolyRootSolver { 
public: 
    PolyRoot calcRoot(const Polynom& poly) { 
     // Implementation based on MPFRC++ precision 
    } 
}; 

class RootSolverFactory { 
public: 
    RootSolverFactory(const std::string configFile) { 
     // Read config file and install a mechanism to watch for changes 
    } 

    std::unique_ptr<IPolyRootSolver> getConfiguredPolyRootSolver() { 

     if(config file contains type = double) { 
      return make_unique<IPolyRootSolver>(new DoublePolyRootSolver()); 
     } 
     else if(config file contains type = long double) { 
      return make_unique<IPolyRootSolver>(new LongDoublePolyRootSolver()); 
     } 
     else if(config file contains type = MPFRC) { 
      return make_unique<IPolyRootSolver>(new MPFRCPolyRootSolver()); 
     } 
     else { 
      // Handle the default case 
     } 
}; 

我希望你明白我的意思。


正如在评论中提到,你也可以使用自由站立功能从一个命名空间,而不是上面提到的抽象接口解决方案:

namespace PolyRootDoublePrecision { 
    PolyRoot calcRoot(const Polynom&); 
} 

namespace PolyRootLongDoublePrecision { 
    PolyRoot calcRoot(const Polynom&); 
} 

namespace PolyRootMPFRCPrecision { 
    PolyRoot calcRoot(const Polynom&); 
} 

class RootSolverFactory { 
public: 
    RootSolverFactory(const std::string configFile) { 
     // Read config file and install a mechanism to watch for changes 
    } 

    std::function<PolyRoot (const Polynom&)> getConfiguredPolyRootSolver() { 

     if(config file contains type = double) { 
      return std::function<PolyRoot (const Polynom&)> 
         (PolyRootDoublePrecision::calcRoot); 
     } 
     else if(config file contains type = long double) { 
      return std::function<PolyRoot (const Polynom&)> 
         (PolyRootLongDoublePrecision::calcRoot); 
     } 
     else if(config file contains type = MPFRC) { 
      return std::function<PolyRoot (const Polynom&)> 
         (PolyRootMPFRCPrecision::calcRoot); 
     } 
     else { 
      // Handle the default case 
     } 
}; 

除了使用配置文件,您可以考虑选择使用其他标准作为配置文件的策略。

E.g.就您的情况而言,似乎多项式表达式的复杂性(即子项的数量)对于选择使用的最佳策略起着至关重要的作用。所以你可以写一些代码,如

std::function<PolyRoot (const Polynom&)> getPolyRootSolver(const Polynom& polynom) { 

     if(polynom.complexity() < 7) { 
      return std::function<PolyRoot (const Polynom&)> 
         (PolyRootDoublePrecision::calcRoot); 
     } 
     else if(polynom.complexity() >= 7 && 
       polynom.complexity() < 50) { 
      return std::function<PolyRoot (const Polynom&)> 
         (PolyRootLongDoublePrecision::calcRoot); 
     } 
     else if(polynom.complexity() >= 50) { 
      return std::function<PolyRoot (const Polynom&)> 
         (PolyRootMPFRCPrecision::calcRoot); 
     } 
}; 
+0

我认为这称赞其他答案就好。我已经有了根解析器作为命名空间,但它可以很容易地进行转换。只是,它相当大,并且可能会以代码大小为代价。对于我的问题的模糊性,我感到很遗憾,但为了更清楚地了解范围,我想到的是http://www.linear.com/designtools/software/#LTspice。你可以添加'.opt numdgt = 7',任何'> = 7'都会使用'double'而不是'float',所以我想知道如果配置不能完成,因为我的程序只用于多项式与合作 –

+0

@aconcernedcitizen另一种简化工厂(无接口)的方法是使用'std :: function '作为'getConfiguredPolyRootSolver()'函数的返回类型,如果您已经有独立的函数一个名字空间。 –

+0

这是一个很好的答案,对于初学者来说,它证明是一个很好的起点,所以我将其标记为答案。 –