C++ 通过配置文件在运行时选择变量类型

C++ 通过配置文件在运行时选择变量类型,c++,type-conversion,runtime,C++,Type Conversion,Runtime,我已经看到了一些关于在运行时动态选择变量类型的答案(,和,以及从那里开始的链接),但是,即使有些可能有点超出我的理解(对C++来说相当陌生),有没有办法从配置文件中读取变量类型并在运行时使用它 例如,配置可以将type=double作为一行,并且可以通过程序的设置更改为type=long double,并在不重新启动应用程序的情况下使用该变量类型 我需要计算一些多项式的根。有些,即使是小订单,也需要高精度,如果达到高订单,则需要更高的精度。尽管如此,对于足够小的数字,我仍然可以取消double

我已经看到了一些关于在运行时动态选择变量类型的答案(,和,以及从那里开始的链接),但是,即使有些可能有点超出我的理解(对C++来说相当陌生),有没有办法从配置文件中读取变量类型并在运行时使用它

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



我需要计算一些多项式的根。有些,即使是小订单,也需要高精度,如果达到高订单,则需要更高的精度。尽管如此,对于足够小的数字,我仍然可以取消
double
longdouble
,但随着我越来越高,我需要MPFRC++(这就是我目前正在唱的歌)。我希望避免因为仅在需要时才能够使用高精度而导致的速度减慢(即使对于较小的订单来说这不是很明显)。

您可能会使用的是与和适当的接口。大致如下:

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
    }
};

类RootSolverFactory{
公众:
RootSolverFactory(const std::string configFile){
//读取配置文件并安装机制以监视更改
}
std::unique_ptr getConfiguredPolyRootSolver(){
if(配置文件包含type=double){
返回make_unique(新的DoublePolyRootSolver());
}
else if(配置文件包含type=long double){
返回make_unique(新的LongDoublePolyRootSolver());
}
else if(配置文件包含type=MPFRC){
返回make_unique(新的MPFRCPolyRootSolver());
}
否则{
//处理默认情况
}
};
我希望你明白我的意思


如注释中所述,您还可以使用命名空间中的独立函数,而不是上述抽象接口解决方案:

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
         }
};
名称空间PolyRootDoublePrecision{
多根calcRoot(常数多项式&);
}
命名空间PolyRootLongDoublePrecision{
多根calcRoot(常数多项式&);
}
命名空间polyRootMPFRCPrection{
多根calcRoot(常数多项式&);
}
类RootSolverFactory{
公众:
RootSolverFactory(const std::string configFile){
//读取配置文件并安装机制以监视更改
}
std::函数getConfiguredPolyRootSolver(){
if(配置文件包含type=double){
返回std::函数
(PolyRootDoublePrecision::calcRoot);
}
else if(配置文件包含type=long double){
返回std::函数
(PolyRootLongDoublePrecision::calcRoot);
}
else if(配置文件包含type=MPFRC){
返回std::函数
(PolyRootMPFRCPrection::calcRoot);
}
否则{
//处理默认情况
}
};

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

例如,对于您的情况,多项式表达式的复杂性(即子项的数量)似乎对选择最佳策略起着至关重要的作用。因此,您可以编写如下代码

    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);
         }
};
std::函数getPolyRootSolver(常数多项式和多项式){
if(多项式复杂性()<7){
返回std::函数
(PolyRootDoublePrecision::calcRoot);
}
else如果(多项式复杂性()>=7&&
多项式复杂性()<50){
返回std::函数
(PolyRootLongDoublePrecision::calcRoot);
}
else if(polynom.complexity()>=50){
返回std::函数
(PolyRootMPFRCPrection::calcRoot);
}
};

在C++程序中使用的所有变量类型都是在编译时确定并实例化的。也许你可以链接其中的一些答案,我们可以解释那里做了什么。也许你可以用if if(type = =“double”)。否则,……“NathoLover,然后不,谢谢你的答案。虽然我不认为这种下降投票是对C++初学者的一种激励。对于知识渊博的人,答案可能是显而易见的,对我来说,它不是。”AcCurnNeDeNe公民OK,所以我们假设你可以在运行时改变数据类型。g这个?我认为这很好地补充了其他答案。我已经有了根解算器作为名称空间,但它可以很容易地进行转换。只是,它相当大,并且可能会以代码大小为代价。我很抱歉我的问题很模糊,但是,为了更清楚地了解范围,我想到的是。您可以添加
。opt numdgt=7
和任何
=7
都将使用
double
而不是
float
,因此我想知道配置是否也不能做到这一点,因为我的程序只用于多项式&co.@aconcernedcidentity。另一种简化工厂的方法(没有接口),正在使用
std::function
作为
getConfiguredPolyRootSolver()的返回类型
function,如果名称空间中已经有独立函数。这是一个很好的答案,对于初学者来说,这是一个很好的起点,因此我将此标记为答案。@AconedCitizen我更新了答案,以获得更广泛的覆盖范围。事实上,最后一部分看起来更适合。它仍然需要3倍的much代码,但也许我可以通过不重用所有辅助函数来逃避,只是可能。我看得越多,它似乎越是最佳选择。我目前的方法是为MPFRC++根查找传递一个可变精度,类似于
64+8*N
,它随多项式的类型而变化。但根查找是
    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);
         }
};