懒惰的__FILE__和__LINE__人口

时间:2019-05-28 15:36:49

标签: c++ file macros line lazy-evaluation

所以我有一个要评估结果的函数,如果结果失败,该函数将记录文件和行号:

void foo(const bool is_failure, const char* file = __FILE__, const int line = __LINE__) {
    if(is_failure) cout << "Failure returned at " << file << '#' << line << endl;
}

我可以像foo(func())这样称呼它,如果func返回true,那么foo将注销失败。问题是fileline参数返回了声明foo的文件和行。除了使用宏之外,还有其他方法可以实现此目的吗?

1 个答案:

答案 0 :(得分:2)

  

有没有一种方法可以实现这一目标...

是的

您可以编写一个类似于函数的宏,该宏扩展为函数调用,并将__FILE____LINE__作为参数传递。由于宏是在调用站点上展开的,因此以下行即填充了这些宏:

#define FOO(arg) foo((arg), __FILE__, __LINE__);
  

...除了使用宏之外?

我不这么认为。 __FILE____LINE__是预处理器宏。预处理总是在编译之前进行。

没有(那些)宏,在标准C ++中无法实现等效功能。在n4519中提出了非宏功能std::source_location作为技术规范。当作为默认参数传递时,它将由调用站点填充。提案中的示例:

struct s {
    source_location member = source_location::current();
    int other_member;

    s(source_location loc = source_location::current())
        : member(loc)   // values of member will be from call-site
    {}

    s(int blather)      // values of member should be hereabouts
        : other_member(blather)
    {}

    s(double)           // values of member should be hereabouts
    {}
};

适合您的功能:

void foo(const bool is_failure, source_location loc = source_location::current());

直到(且除非)此功能已纳入标准中,您都可以依赖宏或GCC中特定于实现的功能(例如__builtin_LINE__builtin_FILE)来实现{ {1}}或等价物。