创建断言函数时遇到麻烦



这是我的断言函数(它不会编译"错误C2110: '+':不能添加两个指针"):

#define CHAR(x) #x
template<typename T>
inline void ASSERT(T x)
{
    if(!x)
    {
        std::string s("ERROR! Assert " + CHAR(x) + " failed. In file " + __FILE__ +
                      " at line " + __LINE__ + ".");
            std::wstring temp(s.length(), L' ');
            std::copy(s.begin(), s.end(), temp.begin());
            getLogger().Write(temp);
        }
    }

有什么好办法吗?

字符串字量很容易被简化为char指针,不能像"ERROR! Assert " + CHAR(x) + " failed. In file "...那样添加。然而,c++有一个方便的特性,可以在编译前自动执行 !(预处理器做这个)。更棒的是,它有一个方便的工具可以在编译时生成宽字符串。所以,你想要:

#define _T(x) L ## x
#define CHAR(x) #x
#define CHAR2(x) CHAR(x)
#define ASSERT(x) ASSERT2(x, CHAR(x), __FILE__, CHAR2(__LINE__))
#define ASSERT2(x, t, f, l) 
if(!x) 
    getLogger().Write(L"ERROR! Assert " _T(t) L" failed. In file " _T(f) L" at line " _T(l) L".");
http://ideone.com/0ibcj

编译器错误很明显;您正在尝试将+操作符应用于字符串字面值。修复它的一个快速方法是在std::string()中包含第一个字符串文字。

正如@James McNellis指出的,注意FILELINE将指向assert函数声明的文件和行。

不能使用+运算符将两个char*连接起来;你需要设置printf或者类似的样式

"ERROR! Assert "是一个以null结尾的c风格字符串。你不能在上面执行operator+

几个问题:

  1. 一般情况下,assert应该进入调试器或转储(如果没有附加)。
  2. 如前所述,LINEFILE需要在宏中使用。
  3. 你需要几个"助手"宏来让字符串正常工作

试着这样做:

#define ASSERT_QUOTE_(x) #x
#define ASSERT_QUOTE_(x) ASSERT_QUOTE_(x)
#define MY_ASSERT(cond) 
  if(cond) {} else { 
    std::stringstream ss; 
    ss << "ERROR! Assert " << ASSERT_QUOTE(cond) << " failed. In file " << __FILE__ << " at line " << __LINE__ << "."; 
    getLogger().Write(ss.str()); 
  }
但是,要小心在这里使用STL。我建议您让记录器的Write()函数接受变量参数并使用printf()或boost::format
处理它们

最新更新