2017-03-05 84 views
1

相關的代碼是:編譯器無法推斷出模板類型返回

std::fstream fout("Logs.txt"); 
class Logs; 
typedef std::ostream& (*ostream_manipulator2)(std::ostream&); 
class LogsOutput 
{ 
public: 
    LogsOutput() {} 
    ~LogsOutput() {} 
    Logs * pLogs; 
    friend LogsOutput& operator<<(LogsOutput &logsClass, std::string &strArg); 
    friend LogsOutput& operator<<(LogsOutput &logsClass, const char *strArg); 
    friend LogsOutput& operator<<(LogsOutput &logsClass, ostream_manipulator2 pf); 
    friend LogsOutput& operator<<(LogsOutput &logsClass, uint64_t number); 
}; 
LogsOutput *pLogsOutput; 
template <typename T> 
T& LOUToutput() 
{ 
        if (pLogsOutput) 
        { 
         return (*pLogsOutput); 
        } 
        else 
         return fout; 
} 

我想調用這個函數這樣:

LOUToutput() << "Print this line " << std::endl; 

但有時候不會創建LogsOutput類,因此解引用它的指針會崩潰,在這種情況下,我寧願輸出到文件。 據我所知,編譯器不能在編譯時告訴LogsOutput類是否會被實例化,因此不能推斷出模板的類型,但我沒有看到任何其他方式可以使它工作。 所以我的問題是我的函數如何根據運行時條件返回不同的類型?

+0

如果您需要在運行時類型來區分,你有沒有考慮建立一個返回超類的功能,並根據您關心的任何運行時情況在運行時返回該類的兩個子類之一?模板實例化在編譯時發生,根據類的特定類型在運行時解決要調用的虛擬方法的實現。 – AustinZ

回答

2

複雜的解決方案是使用繼承。如果您要從std :: ostream繼承,則可以返回一個公共基類(如果您有興趣,請參閱以下討論:How to inherit from std::ostream?

更簡單的解決方案imo。將返回重定向輸出的代理類有必要的。

struct LogProxy { 
    LogsOutput *pLog; 
    // ... 
    LogProxy &operator<<(std::string &o) { 
     if(pLogsOutput) { 
      *pLog << o; 
     } else { 
      // Assuming this is available as a global.. You probably don't want to do that 
      fout << o; 
     } 
     return *this; 
    } 
    // .... 
}; 

LogProxy LOUToutput() { 
    return LogProxy { pLogsOutput; }; 
} 

其他一些一般性意見:

  1. 如果你想使用模板,你需要使這個編譯時的條件。你可以使用類似std :: enable_if <>來提供LOUToutput()的多個模板重載,它在編譯時選擇登錄到的時間。

  2. 我猜這只是爲了張貼到SO的目的,但是你的代碼有多個全局變量在頭文件中聲明。你需要解決這個問題。

  3. 你的代碼沒有常量聲明。很多這些運算符看起來應該至少在其輸出(string,.etc。)參數中聲明爲const。

編輯:這裏是工作(編譯正確)這個想法的樣本:

#include <iostream> 

struct PRXY { 
    bool cond; 

    const PRXY &operator<<(const std::string &t) const { 
     if(cond) { 
      std::cout << t; 
     } else { 
      std::cerr << t; 
     } 
     return *this; 
    } 
}; 

PRXY pr(bool cond) { 
    return PRXY { cond }; 
} 

void test() { 
    pr(false) << "Hello"; 
} 
+0

謝謝,這個代理想法運作良好。 – user

相關問題