我最近写了一个记录器类。在编译此代码时:
std::ofstream *stream = new std::ofstream;
stream->open( log_file_name.c_str() );
assert( stream->is_open() );
logger( stream, std::string("blurp") );我知道错误:
no match for call to '(name::space::logger)( std::ofstream*&, std::string )'关于最后一行代码。
定义记录器的头文件是:
namespace name {
namespace space {
class logger {
private:
std::ofstream *stream;
std::string name;
public:
void log( std::string, std::string );
logger( std::ofstream *, std::string );
logger();
};
}
}我在那里实现了所有原型的函数/构造函数,没有错误。
是什么导致了这一切?谢谢你抽出时间埃克林。
发布于 2014-03-21 08:53:53
编译器认为您正在对一个名为operator()的对象调用logger。您想要做的似乎是创建一个logger实例:
logger log(stream, std::string("blurp") );在这里,log是类name::space::logger的一个实例。
发布于 2014-03-21 09:58:13
首先,没有必要为ostream使用指针。因为这不是Java,所以可以在堆栈上创建对象,而无需使用new。
然后,您的编译器似乎没有看到logger让构造函数接受流指针和字符串。通过调用,它假定签名必须类似于std::ofstream*&, std::string,但是您提供的构造函数与这个假设完全匹配(请参阅Sebastian的答案以获得详细信息)。
那么,这里有什么问题吗?
logger )。#include指令找到了一个较旧的版本,而不是您放置构造函数的版本。最好的办法是在头中引入一些明显的错误,然后再编译一次。如果编译器没有抱怨错误,那么它显然不包含正在编辑的标头。发布于 2014-03-21 10:54:07
GCC用这种奇怪的方式向函数报告论点的类型。
当你这样做时:
logger( stream, std::string("blurp") );编译器看到对记录器构造函数(name::space::logger)的调用,第一个参数是std::ostream*类型的lvalue (在本例中是一个普通变量),第二个参数是std::string类型的rvalue (临时构造的)。它将此报告为调用签名(name::space::logger)(std::ostream*&, std::string) --此处的& (lvalue引用)仅表示参数为lvalue。这不影响将其与参数类型std::ostream*匹配的能力。
https://stackoverflow.com/questions/22554089
复制相似问题