2016-02-11 79 views
0

嘗試寫例外模板構造函數類,因此拋出異常的時候,我可以把可變長度參數,來到某事像這樣:模板的構造

namespace miniReader{ 

    namespace Exception{ 

     template<typename deriverEx, typename baseType> 
     class Exception : public baseType{ 
      std::string errorClass; 
      mutable std::string exStrMsg; 
     protected: 
      static std::stringstream exMsg; 
      std::string whatMessage; 
      // Exception(const Exception& other): baseType(""){} 

      const char* what() const noexcept{ 
       if(exStrMsg.empty()){ 
        exStrMsg = exMsg.str(); 
       } 
       exMsg.str(""); 
       return exStrMsg.c_str(); 
      } 

      ~Exception() noexcept { 
      } 
     public: 
      Exception(): baseType("") { 
      } 
     }; 

     class miniRuntimeException : public Exception<miniRuntimeException, std::runtime_error>{ 
     public: 
      miniRuntimeException(): Exception() {} 

      template<typename T, typename...Args> 
      miniRuntimeException(T first, Args...arg): Exception(){ 
       LOG(first, this); 
       exMsg << first << " "; 
       miniRuntimeException(arg...); 
      } 
     }; 

    template<typename deriverEx, typename baseType> 
    std::stringstream Exception<deriverEx, baseType>::exMsg; 

    } 
} 

現在我可以寫拋出異常這樣的:

miniRuntimeException(__FILE__, __LINE__, "Failed opening file", "Runtime Exception") 

我已經做了exMsg靜態,因爲在其他情況下,我可以得到所有的模板參數。所以我的問題是,Exception類中的exMsg是靜態的,所以當派生類構造函數被調用時(variadic模板),讀取參數是正確的。我找不到一種方法使它不是靜態的,因爲exMsg只會得到一個模板參數。有沒有辦法做到這一點?接下來的問題是當我的模板構造函數被調用時,爲每個參數創建新對象(是否正確?)以及如何在這種情況下我可以在這些對象之間傳遞信息,如更新exMsg,因此它將在最終對象中完成?

+0

你的問題一般不是很清楚...... – callyalater

回答

0

我想我理解了這個問題(在閱讀3次後)。我建議用下面的代碼替換構造的鏈(繼承被遺漏的,爲了清楚起見):

class miniException { 
    std::stringstream msg; 
public: 
    template<class... ARGS> miniException(ARGS... args) { 
     populate_msg(args...); 
    } 
private: 
    template<class T, class... ARGS> void populate_msg(T t, ARGS... args) { 
     msg << t << " "; 
     populate_msg(args...); 
    } 
}; 
void populate_msg() { } 

P.S.你可能實際上想通過const引用而不是一個值來接受參數。

+0

謝謝,這就是工作。想知道爲什麼Exception類需要顯式拷貝構造函數:* Exception(const Exception&other):baseType(「」){LOG(「Copy constructor」);} *然而它永遠不會被調用,並且當它沒有提供時,我會收到錯誤:*錯誤:使用已刪除的函數'std :: __ cxx11 :: basic_stringstream <_CharT,_Traits,_Alloc> :: basic_stringstream(const std :: __ cxx11 :: basic_stringstream <_CharT,_Traits,_Alloc>&)[with _CharT = char; _Traits = std :: char_traits ; _Alloc = std :: allocator ] *謝謝 – user3655463

+0

因爲'std :: basic_stringstream'確實有一個複製構造函數被聲明爲已刪除。被調用或不被調用並不重要,因爲編譯器會爲您的異​​常類生成升級副本。實際上你應該將你的定義定義爲刪除,而不是創建一個虛擬的。 – SergeyA

+0

感謝您的回覆,想勾選您的回答有用,但沒有足夠的聲譽不幸。 – user3655463