简体   繁体   English

无法专门化功能模板。 重载运算符<

[英]Failed to specialize function template. Overloading operator<<

I'm trying to make a logger which logs to std::cout and to a file. 我正在尝试创建一个记录到std :: cout和文件的记录器。 This is my class: 这是我的班级:

.h file: .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 file .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() {}

Then if I try to do: 然后,如果我尝试做:

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

I get: 我明白了:

1>f:\\dropbox\\workspace - visual studio\\peuler\\peuler\\problemsmanager.cpp(47): error C3767: '<<': candidate function(s) not accessible 1> could be the friend function at 'f:\\dropbox\\workspace - visual studio\\peuler\\peuler\\problemsmanager.h(37)' : '<<' [may be found via argument-dependent lookup] 1> f:\\ dropbox \\ workspace - visual studio \\ peuler \\ peuler \\ problemsmanager.cpp(47):错误C3767:'<<':候选函数不可访问1>可能是'f:\\的朋友函数dropbox \\ workspace - visual studio \\ peuler \\ peuler \\ problemsmanager.h(37)':'<<'[可以通过参数依赖查找找到]

There are a couple of issues with your templates, the first is that both differ only on the reference, and that will cause issues. 您的模板存在一些问题,第一个问题是两者仅在引用方面存在差异,这会导致问题。 You only want one (that reads and does not write to the argument): 你只需要一个(读取和不写入参数):

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

Now the second problem is that the templates should be defined somewhere where the compiler can see it when generating the instantiation. 现在第二个问题是应该在生成实例化时编译器可以看到的位置定义模板。 That basically means that the definition must be in the header, not in the .cpp file. 这基本上意味着定义必须在标题中,而不是在.cpp文件中。 [*] [*]

Beyond that, since the logger type is private to ProblemsManager , you cannot access it from the namespace level, so you will have issues defining the free function, since it cannot access the nested type. 除此之外,由于logger类型是ProblemsManager专用的,因此您无法从命名空间级别访问它,因此您将无法定义自由函数,因为它无法访问嵌套类型。 The options would be making the type public, making the function also a friend of ProblemsManager , or as I would recommend, just define the template inline inside the class definition: 选项是将类型设置为public,使该函数也成为ProblemsManager的朋友,或者正如我所建议的那样,只需在类定义中内联定义模板:

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

[*] This might actually be the exception to the rule, since being a private type, I can only assume that all uses of the logger and thus the operator<< will happen within the translation unit that defines ProblemsManager members. [*]这实际上可能是规则的例外,因为作为私有类型,我只能假设logger所有使用以及operator<<将在定义ProblemsManager成员的转换单元中发生。 If that is the case, you can disregard this paragraph. 如果是这种情况,您可以忽略这一段。

As operator<< functions are not members but friends you cannot use 'this' inside them. 由于操作符<<函数不是成员而是朋友,因此您不能在其中使用'this'。 You probably want to return 'log' there and appropriately qualify log members with 'log.'. 您可能希望在那里返回“log”并使用“log”适当地限定日志成员。

I'll give it a long shot. 我会给它一个远景。

log<<"test";

The above call is a call to operator<< function with the first parameter of logger & and a second of const char[5]. 上面的调用是使用logger的第一个参数和第二个const char [5]调用operator << function。

The first overload probably cannot bind as you are overloading on reference and passing const object. 第一个重载可能无法绑定,因为您在引用上重载并传递const对象。 The second fails as you are passing array by value and you cannot do that. 第二个失败,因为你按值传递数组,你不能这样做。 I am just not sure why your array in not collapsing to a pointer. 我只是不确定为什么你的数组没有折叠到指针。

Have you tried to overload on const reference? 你试过重载const引用吗? And by the way - why do you overload on value and reference? 顺便说一下 - 为什么你的价值和参考超载?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM