相关代码为: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类是否将被实例化,因此无法推断出模板的类型,但是我看不到任何其他方法可以使它工作。所以我的问题是我的函数如何根据运行时条件返回不同的类型? 最佳答案 复杂的解决方案是使用继承。如果要从std::ostream继承,则可以返回一个公共(public)基类(如果您感兴趣,请在这里进行讨论: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; };}其他一些一般性评论:如果要使用模板,则需要将其设为编译时条件。您可以使用std::enable_if 之类的东西来提供LOUToutput()的多个模板重载,这些重载在编译时选择登录的位置。 我猜这只是出于发布到SO的目的,但是您的代码在头文件中声明了多个全局变量。您需要解决该问题。 您的代码上没有const声明。许多这些运算符看起来至少应该在其输出(字符串等)参数上声明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";}关于c++ - 编译器无法推断出要返回的模板类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42613637/ 10-14 17:12