Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 解决基本模板类成员的模糊性_C++_Templates_Ambiguity_Boost Log - Fatal编程技术网

C++ 解决基本模板类成员的模糊性

C++ 解决基本模板类成员的模糊性,c++,templates,ambiguity,boost-log,C++,Templates,Ambiguity,Boost Log,我有一个类的层次结构,每个类都必须有一个特定的基类。Than基类提供了发布日志记录和获取日志通道的名称(基本上是使用日志的类的名称)的能力。让我们调用这个类Logable 为了允许我的类多次从这个Logable类继承,我给了它一个模板参数,每个后代都将自己用作这个参数 实际上,我使用的是boost::log库,但是有一个非常简单的例子,上面提到的层次结构使用simpleLogableImpl类来代替boost::log sink #include <iostream> #includ

我有一个类的层次结构,每个类都必须有一个特定的基类。Than基类提供了发布日志记录和获取日志通道的名称(基本上是使用日志的类的名称)的能力。让我们调用这个类
Logable

为了允许我的类多次从这个
Logable
类继承,我给了它一个模板参数,每个后代都将自己用作这个参数

实际上,我使用的是boost::log库,但是有一个非常简单的例子,上面提到的层次结构使用simple
LogableImpl
类来代替boost::log sink

#include <iostream>
#include <string>

// macro for logging in a boost::log style
#define LOG_DEBUG this->_loggerObj.logStream("debug")
#define LOG_INFO  this->_loggerObj.logStream("info")
#define LOG_WARN  this->_loggerObj.logStream("warning")
#define LOG_ERROR this->_loggerObj.logStream("error")


class LogableImpl
{
private:
   std::string _channelName;
public:
   LogableImpl(const std::string & channelName): _channelName(channelName) {}

   std::ostream & logStream(const std::string & severetyLevel)
   {
      std::cout << _channelName << " " << severetyLevel;
      return std::cout;
   }
};


template <class Descendant>
class Logable
{
protected:
   Logable(const std::string & channelName): _loggerObj(channelName) {}
   LogableImpl _loggerObj;
};


class Base: private Logable<Base>
{
public:
   Base()
      : Logable<Base>("Base")
   {}

   void someMethod()
   {
      LOG_INFO << "some method is called" << std::endl;
      LOG_ERROR << "an error happened" << std::endl;
   }
};


class Derived: public Base, private Logable<Derived>
{
public:
   Derived()
      : Logable<Derived>("Derived")
   {}

   void someAnotherMethod()
   {
      LOG_INFO << "another method is called" << std::endl;
      LOG_ERROR << "another error is happened" << std::endl;
   }
};


int main()
{
   Base b;
   Derived d;
   b.someMethod();
   d.someMethod();

   return 0;
}
#包括
#包括
//用于以boost::log样式记录的宏
#定义LOG_DEBUG this->_loggerObj.logStream(“DEBUG”)
#定义LOG\u INFO this->\u loggerObj.logStream(“INFO”)
#定义LOG\u WARN this->\u loggerObj.logStream(“警告”)
#定义LOG\u ERROR this->\u loggerObj.logStream(“错误”)
类LogableImpl
{
私人:
std::string\u channelName;
公众:
LogableImpl(const std::string和channelName):\u channelName(channelName){}
std::ostream和logStream(const std::string和severetyLevel)
{

std::cout我使用c++11通过明确指定应该使用哪个
Logable
来实现这一点。因为我们不知道
这个
的类型,所以我使用
decltype

#define LOGABLE_TYPE typename std::remove_reference<decltype(*this)>::type
#define LOG_DEBUG this->Logable<LOGABLE_TYPE>::_loggerObj.logStream("debug")
#define LOG_INFO  this->Logable<LOGABLE_TYPE>::_loggerObj.logStream("info")
#define LOG_WARN  this->Logable<LOGABLE_TYPE>::_loggerObj.logStream("warning")
#define LOG_ERROR this->Logable<LOGABLE_TYPE>::_loggerObj.logStream("error")
#定义可记录类型typename std::remove_reference::TYPE
#定义LOG_DEBUG this->Logable::_loggerObj.logStream(“调试”)
#定义LOG_INFO this->Logable::_loggerObj.logStream(“INFO”)
#定义LOG\u WARN this->Logable::\u loggerObj.logStream(“警告”)
#定义LOG_ERROR this->Logable::_loggerObj.logStream(“错误”)

请参见此处的完整代码:

不幸的是,我找不到一种方法来替换
decltype
,以使msvc 2008能够理解使用Petr的答案。即使
boost::typeof
也不合适(只要我使用正确)

因此,我提出了一个解决方案,使用带有宏的
案例添加了一个

#include <iostream>
#include <string>

#define USE_APPROPRIATE_LOGGER(classname) using Logable<classname>::_loggerObj
#define LOG_DEBUG _loggerObj.logStream("debug")
#define LOG_INFO  _loggerObj.logStream("info")
#define LOG_WARN  _loggerObj.logStream("warning")
#define LOG_ERROR _loggerObj.logStream("error")

class LogableImpl
{
private:
   std::string _channelName;
public:
   LogableImpl(const std::string & channelName): _channelName(channelName) {}

   std::ostream & logStream(const std::string & severetyLevel)
   {
      std::cout << _channelName << " " << severetyLevel << " ";
      return std::cout;
   }
};


template <class Descendant>
class Logable
{
protected:
   Logable(const std::string & channelName): _loggerObj(channelName) {}
   LogableImpl _loggerObj;
};

class Base: private Logable<Base>
{
   USE_APPROPRIATE_LOGGER(Base);
public:
   Base()
      : Logable<Base>("Base")
   {}

   void someMethod()
   {
      LOG_INFO << "some method is called" << std::endl;
      LOG_ERROR << "an error happened" << std::endl;
   }
};

class Derived: public Base, private Logable<Derived>
{
   USE_APPROPRIATE_LOGGER(Derived);
public:
   Derived()
      : Logable<Derived>("Derived")
   {}

   void someAnotherMethod()
   {
      LOG_INFO << "another method is called" << std::endl;
      LOG_ERROR << "another error is happened" << std::endl;
   }
};


int main()
{
   Base b;
   Derived d;
   b.someMethod();
   std::cout << std::endl;
   d.someAnotherMethod();

   return 0;
}
#包括
#包括
#使用Logable::\u loggerObj定义使用适当的记录器(类名)
#定义LOG_DEBUG_loggerObj.logStream(“调试”)
#定义LOG\u INFO\u loggerObj.logStream(“INFO”)
#定义LOG\u WARN\u loggerObj.logStream(“警告”)
#定义LOG\u ERROR\u loggerObj.logStream(“错误”)
类LogableImpl
{
私人:
std::string\u channelName;
公众:
LogableImpl(const std::string和channelName):\u channelName(channelName){}
std::ostream和logStream(const std::string和severetyLevel)
{

std::cout-Well,你想在
派生的
案例中使用哪个
\u loggerObj
呢?@Barry-那一个,也就是直接
可登录的
案例谢谢你的回答。对不起,我忘了提到它必须在MSVC 2008中完成,它不支持C++11xYes,我也一直在考虑使用
使用
来工作没有c++11,就没有时间让它运行。
#include <iostream>
#include <string>

#define USE_APPROPRIATE_LOGGER(classname) using Logable<classname>::_loggerObj
#define LOG_DEBUG _loggerObj.logStream("debug")
#define LOG_INFO  _loggerObj.logStream("info")
#define LOG_WARN  _loggerObj.logStream("warning")
#define LOG_ERROR _loggerObj.logStream("error")

class LogableImpl
{
private:
   std::string _channelName;
public:
   LogableImpl(const std::string & channelName): _channelName(channelName) {}

   std::ostream & logStream(const std::string & severetyLevel)
   {
      std::cout << _channelName << " " << severetyLevel << " ";
      return std::cout;
   }
};


template <class Descendant>
class Logable
{
protected:
   Logable(const std::string & channelName): _loggerObj(channelName) {}
   LogableImpl _loggerObj;
};

class Base: private Logable<Base>
{
   USE_APPROPRIATE_LOGGER(Base);
public:
   Base()
      : Logable<Base>("Base")
   {}

   void someMethod()
   {
      LOG_INFO << "some method is called" << std::endl;
      LOG_ERROR << "an error happened" << std::endl;
   }
};

class Derived: public Base, private Logable<Derived>
{
   USE_APPROPRIATE_LOGGER(Derived);
public:
   Derived()
      : Logable<Derived>("Derived")
   {}

   void someAnotherMethod()
   {
      LOG_INFO << "another method is called" << std::endl;
      LOG_ERROR << "another error is happened" << std::endl;
   }
};


int main()
{
   Base b;
   Derived d;
   b.someMethod();
   std::cout << std::endl;
   d.someAnotherMethod();

   return 0;
}