可以#define预处理器指令包含if和else? [英] Can #define preprocessor directive contain if and else?

查看:219
本文介绍了可以#define预处理器指令包含if和else?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是从这个链接尝试记录器代码,但它给我错误。 如何实现良好的调试/日志记录功能项目

  #ifndef _LOGGER_HPP_ 
#define _LOGGER_HPP_

#include < iostream>
#include< sstream>

/ *考虑添加boost线程id,因为我们想要知道它的写入和
*不想为每次调用重复它* /

/ *考虑添加策略类以允许用户通过命令行将日志记录重定向到特定的
*文件
* /

enum loglevel_e
{logERROR,logWARNING, logINFO,logDEBUG,logDEBUG1,logDEBUG2,logDEBUG3,logDEBUG4};

class logIt
{
public:
logIt(loglevel_e _loglevel = logERROR){
_buffer< _loglevel<< :
<< std :: string(
_loglevel> logDEBUG
?(_loglevel - logDEBUG)* 4
:1
,'');
}

template< typename T>
logIt&运算符<<(T const& value)
{
_buffer<值;
return * this;
}

〜logIt()
{
_buffer< std :: endl;
//这是根据POSIX标准的原子
// http://www.gnu.org/s/libc/manual/html_node/Streams-and-Threads.html
std :: cerr<< _buffer.str();
}

private:
std :: ostringstream _buffer;
};

extern loglevel_e loglevel;

#define log(level)\
if(level> loglevel); \
else logIt(level)

#endif

更确切地说,此 #define 会产生错误:

  #define log (level)\ 
if(level> loglevel); \
else logIt(level)

错误是语法错误:如果语法错误:else



我将 #includelogger.hpp main.h 移动到 main.cpp ,问题消失了。



任何想法?

如果 loglevel 在编译时已知,您可以执行以下操作:

 模板< bool> 
struct LogSystem
{
template< class T>
LogSystem&运算符<< (const T&)
{
//忽略输入
return(* this);
}
};

模板<>
struct LogSystem< true>
{
template< class T>
LogSystem&运算符<< (const T& v)
{
cout< v;
return(* this);
}
};

template< bool B>
LogSystem< B> getLog()
{
return LogSystem< B>();
}

#define log(level)getLog< (level <= loglevel)>()

if loglevel 在编译时是未知

  class iLogSystem 
{
public:
virtual iLogSystem&运算符<< (const int&)
{
//空
return(* this);
}
virtual iLogSystem&运算符<< (const custom_type&);
{
return(* this);}
}
// make用于记录所有类型的函数
};

class LogSystem:public iLogSystem
{
public:
virtual iLogSystem&运算符<< (const int& v)
{
cout< v;
return(* this);
}
virtual iLogSystem&运算符<< (const custom_type& q);
{
cout<< q.toString();
return(* this);
}
// make用于记录所有类型的函数
};
iLogsystem& getLog(const bool l)
{
static LogSystem actual_log;
static iLogSystem empty_log;
if(l)
return& actual_log;
return& empty_log;
}

#define log(level)getLog(level< = loglevel)


I was trying the logger code from this link, but it gives me error. How to implement a good debug/logging feature in a project

#ifndef _LOGGER_HPP_
#define _LOGGER_HPP_

#include <iostream>
#include <sstream>

/* consider adding boost thread id since we'll want to know whose writting and
 * won't want to repeat it for every single call */

/* consider adding policy class to allow users to redirect logging to specific
 * files via the command line
 */

enum loglevel_e
    {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};

class logIt
{
public:
    logIt(loglevel_e _loglevel = logERROR) {
        _buffer << _loglevel << " :" 
            << std::string(
                _loglevel > logDEBUG 
                ? (_loglevel - logDEBUG) * 4 
                : 1
                , ' ');
    }

    template <typename T>
    logIt & operator<<(T const & value)
    {
        _buffer << value;
        return *this;
    }

    ~logIt()
    {
        _buffer << std::endl;
        // This is atomic according to the POSIX standard
        // http://www.gnu.org/s/libc/manual/html_node/Streams-and-Threads.html
        std::cerr << _buffer.str();
    }

private:
    std::ostringstream _buffer;
};

extern loglevel_e loglevel;

#define log(level) \
if (level > loglevel) ; \
else logIt(level)

#endif

More precisely, this #define is giving errors:

#define log(level) \
if (level > loglevel) ; \
else logIt(level)

The errors are Syntax error: if and Syntax error: else

But later, I noticed that if I move #include "logger.hpp" from main.h to main.cpp, the problem disappeared. Though 'main.h' is included many times in different places, it does contain '#pragma once'.

Any idea?

解决方案

If loglevel is known at compile time you can do the following:

template <bool>
struct LogSystem
{
    template <class T>
    LogSystem& operator << (const T &)
    {
        //ignore the input
        return (*this);
    }
};

template <>
struct LogSystem <true>
{
    template <class T>
    LogSystem& operator << (const T & v)
    {
        cout << v;
        return (*this);
    }
};

template <bool B>
LogSystem<B>    getLog()
{
    return LogSystem<B>();
}

#define log(level) getLog< (level <= loglevel) >()

if loglevel is not known at compile time:

class iLogSystem
{
public:
    virtual iLogSystem& operator << (const int &)
    {
        //empty
        return (*this);
    }
    virtual iLogSystem& operator << (const custom_type &);
    {
        return (*this);
    }
    //make functions for logging all the types you want
};

class LogSystem : public iLogSystem
{
public:
    virtual iLogSystem& operator << (const int & v)
    {
        cout << v;
        return (*this);
    }
    virtual iLogSystem& operator << (const custom_type &  q);
    {
        cout << q.toString();
        return (*this);
    }
    //make functions for logging all the types you want
};
iLogSystem& getLog(const bool l)
{
    static LogSystem actual_log;
    static iLogSystem empty_log;
    if(l)
        return &actual_log;
    return &empty_log;
}

#define log(level) getLog( level <= loglevel )

这篇关于可以#define预处理器指令包含if和else?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆