我最近写了一个记录器类。编译此代码时:
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();
};
}
}
我已经在那里实现了原型的所有函数/构造函数。
可能导致这种情况的原因是什么?谢谢你的时间,Erkling。
答案 0 :(得分:1)
编译器认为您在名为operator()
的对象上调用logger
。看来你想要做的是创建一个logger
实例:
logger log(stream, std::string("blurp") );
此处,log
是类name::space::logger
的实例。
答案 1 :(得分:1)
首先,不需要使用ostream
的指针。由于这不是Java,因此您可以在堆栈上创建对象,而不使用new
。
然后看起来好像你的编译器没有看到logger
有构造函数采用流指针和字符串。从你做的调用来看,签名必须是类似 std::ofstream*&, std::string
,但你提供的构造函数完全符合这个假设(详见Sebastian Redl的答案)。
那么,这里可能出现什么问题?
logger
的某些内容尚未定义)#include
指令找到旧版本而不是您放置构造函数的版本。最有可能找到这个在标题中引入了一些明确的错误并再次编译。如果编译器没有抱怨错误,它显然不包括您正在编辑的标题。答案 2 :(得分:1)
GCC有这种奇怪的方式来报告函数参数的类型。
执行此操作时:
logger( stream, std::string("blurp") );
编译器看到对logger构造函数(name::space::logger
)的调用,第一个参数是类型为std::ostream*
的左值(在本例中为普通变量),第二个参数是右值(a std::string
类型的临时构造。它将此报告为呼叫签名(name::space::logger)(std::ostream*&, std::string)
- 此处&
(左值引用)仅表示参数是左值。这不会影响将其与参数类型std::ostream*
匹配的能力。