2016-11-28 67 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

這是一個很好的答案,對於初學者來說,它證明是一個很好的起點,所以我將其標記爲答案。 –