将模板函数与类混合

时间:2013-09-01 06:20:22

标签: c++ class variadic-functions

我正在创建一个小型日志记录类,它允许使用类似printf的语法(礼貌的boost :: format)使用模板函数来实现可变长度的参数列表。我想我很接近:在实例化一个Log对象'logger'之后,我希望能够编写logger.Print("This %s is a %s", some_obj, another_obj);。我目前拥有它的方式,这会产生错误“在'Log'中没有名为'Print'的成员。”

有谁能建议我需要改变什么?

Log.h:

#ifndef LOG_H
#define LOG_H
#include <string>
using std::string;

#include <sstream>
#include <ostream>
#include <fstream>
#include <boost/format.hpp>

enum Severity {
    DEBUG,
    INFO,
    WARN,
    CRIT,
    DIE,
    LEVELS      // always last; holds # of severity levels
};


class Log {

public:
    Log();
    Log(const char*, const char*);

    void Print_r(int, const boost::format& );

private:
    static const char * sev_code[];

    // order is important here!
    std::ofstream  output_file_stream; // this must be initialized ..
    std::ostream&  output_stream;      // .. before this is bound.
};

int LEVEL; // (where does this belong?)

// This unpacks the variadic arguments one at a time recursively
template <typename T, typename... Params>
    void Print_r (int severity, boost::format &boost_format, const T &arg, const Params&... parameters) {
    Print_r(severity, boost_format % arg, parameters...); // recursively unpack
}

// This checks severity and converts pat to boost::format
template <typename... Params>
void Print (int severity, const string &pat, const Params&... parameters) {
    if (severity < LEVEL) return;
    boost::format boost_format(pat);
    Print_r(severity, boost_format, parameters...);
}

#endif

Log.cpp:

#include "Log.h"
#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

#include <fstream>

const char * Log::sev_code[] = { 
    "DBUG",
    "INFO",
    "WARN",
    "CRIT",
    "DIE "
};

// Constructor w/no parms = logging to cout
Log::Log() :
    output_stream(cout) {

}

// Constructor w/parms = logging to file
Log::Log(const char* dir, const char* file) :
    output_stream(output_file_stream) {

    string output_file_name = string(dir) + "/" + string(file);
    output_file_stream.open(output_file_name.c_str(), std::ofstream::out);
}

// This does the actual logging of the formatted message to the
// output_stream:
void 
Log::Print_r (int severity, const boost::format &boost_format) {
    std::stringstream s;
    s << "[" << sev_code[severity] << "] "
      << boost_format;
    output_stream << s << endl;
}

1 个答案:

答案 0 :(得分:0)

从此代码中,Print模板位于Log类之外。你需要在类定义中移动它。