禁用__LINE__宏?

use*_*114 2 c++ macros

我想做一些异常处理.我打算使用__LINE____FILE__宏.

我有一些标题Vectors.hpp,其中我实现了一个矢量结构的类.在这个类中,我实现了,operator []并且每次将此运算符与out of bounds索引一起使用时,我想抛出一个异常.我在一些源test.cpp中测试了这个类.我希望能够在test.cpp中看到确切的行.

但是我知道__LINE__每次包含一些头文件时都会禁用宏,所以我得到的是Vectors.hpp中的行,我处理异常而不是test.cpp中的行.有没有一个很好的方法来解决这个问题?或者,如何实现自己的__LINE__宏?

Seb*_*ach 5

__LINE__宏从不禁用.在您编写它的地方扩展它.编写代码有两种方法(更确切地说,有两种方法可以生成令牌):

  • 手动编写
  • 使用预处理器编写代码

如果你有它是这样的一些文件foo.cpp(只是示例,实际上这是非常糟糕的代码)

class Foo {
public:
    Frob operator[] (size_t) { throw __LINE__ }
};
Run Code Online (Sandbox Code Playgroud)

那么__LINE__总是3而且__FILE__永远foo.cpp.

那是因为宏在使用它们的地方扩展了.解决方案是找到一种方法将它们扩展到您想要的位置,唯一的方法是定义另一个宏:

#define safe_subscript(foo, index) \
      try {foo[index];} \
      catch(...) { std::cout << __LINE__ << '\n'; }

....
safe_subscript(foo, 256);
Run Code Online (Sandbox Code Playgroud)

但正如您所看到的,这会导致相当丑陋的代码和变通方法.

真正的解决方案:只是在超出边界(throw std::out_of_range)时抛出异常,或者像标准库一样:

T& operator[] (size_type i) { return store_[i]; }
T& at (size_type i) { if (i>size_) throw std::out_of_range("crap");
                      return store_[i]; }

T operator[] (size_type i) const { return store_[i]; }
T at (size_type i) const { if (i>size_) throw std::out_of_range("crap");
                           return store_[i]; }
Run Code Online (Sandbox Code Playgroud)

如果您的用户收到异常,他应该调试他/她/它编程错误的位置.