无法专用化函数模板。重载运算符<<

Failed to specialize function template. Overloading operator<<

本文关键字:lt 运算符 重载 专用 函数模板      更新时间:2023-10-16

我正在尝试制作一个记录器,它将日志记录到std::cout和一个文件。这是我的课:

.h文件:

class ProblemsManager {
        (...)
private:
        (...)
    class logger {
    private: 
        std::ofstream fileStream;
        static const std::string LOG_PATH;
    public: 
        logger();
        ~logger();

    template<class T> 
    friend logger & operator<<(logger &log, const T & bytes) {
        log.fileStream<<bytes;
        std::cout<<bytes;
        return log;
    }
    };
};

.cpp文件

(...)
const std::string ProblemsManager::logger::LOG_PATH = "F:\Dropbox\workspace - Visual Studio\PEuler\PEuler\PEuler.log";
ProblemsManager::logger::logger() : fileStream(LOG_PATH,std::ofstream::out) {}
ProblemsManager::logger::~logger() {}

然后,如果我尝试这样做:

ProblemsManager::logger log;
log<<"test";

我得到:

1> f:\dropbox\workspace-visual studio\peuler\peuler\bproblemsmanager.cpp(47):错误C3767:'<lt;':候选函数不可访问1> 可以是"f:\dropbox\workspace-visionstudio\peuler\peuler\bproblemsmanager.h(37)"中的友元函数:"<lt;'[可通过参数相关查找找到]

您的模板有几个问题,第一个问题是两者仅在引用上不同,这将导致问题。您只需要一个(读取和不写入参数):

    template<class T> 
    friend logger & operator<<(logger& log, const T & bytes);
    //                                      ^^^^^

现在的第二个问题是,应该在编译器生成实例化时可以看到的地方定义模板。这基本上意味着定义必须在标头中,而不是在.cpp文件中[*]

除此之外,由于logger类型对ProblemsManager是私有的,因此无法从命名空间级别访问它,因此在定义自由函数时会遇到问题,因为它无法访问嵌套类型。选项是将类型公开,使函数也是ProblemsManager的朋友,或者正如我所建议的,只需在类定义中内联定义模板:

class ProblemsManager {
private:
    class logger {
        template<class T> 
        friend logger & operator<<(logger& log, T & bytes) {
           // implementation goes here
        } 
    };
};

[*]这实际上可能是规则的例外,因为作为一个私有类型,我只能假设logger的所有使用以及operator<<的所有使用都将发生在定义ProblemsManager成员的转换单元内。如果是这样的话,你可以忽略这一段。

作为运算符<lt;函数不是成员而是朋友,您不能在函数中使用"this"。您可能希望在那里返回"log",并用"log"适当地限定日志成员。

我会给它一个长镜头。

log<<"test";

上述呼叫是对运营商<lt;函数的第一个参数logger&和const char[5]的第二个。

第一个重载可能无法绑定,因为您正在对引用进行重载并传递const对象。第二个失败,因为您正在按值传递数组,但您不能这样做。我只是不知道为什么你的数组没有塌陷到一个指针。

你有没有试图在const引用上重载?顺便说一句,为什么你在价值和参考上超载?