编译器认为我传递了std :: ofstream *&,传递了std :: ofstream *

时间:2014-03-21 08:51:43

标签: c++ pointers

我最近写了一个记录器类。编译此代码时:

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。

3 个答案:

答案 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的答案)。

那么,这里可能出现什么问题?

  1. 编译器根本看不到标题。那是因为你没有包括它。我不认为这是可能的,因为错误信息应该是不同的(关于类logger的某些内容尚未定义)
  2. 编译器会看到另一个版本的标头,它不包含您在此处调用的构造函数。这可能是因为您没有在构造函数中编辑后保存标头,或者您可能将其复制到另一个位置并且#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*匹配的能力。