1
#include <stdio.h>

void print(int a = __LINE__){printf("hello %d\n", a);}

void main(){
  print();
  print();
  print();
  print();
}

__LINE__例中的宏扩展为 3,因此 print 函数以相同的值被调用了 4 次。有没有办法说服编译器在调用点扩展这个宏,以便调用 print 函数6,7,8,9而不是3,3,3,3C++11 中存在的功能?

我的用例:

在我的应用程序中,我提供了多个采用唯一 ID 的函数。每个调用点/位置的 ID 应该是唯一的(因此,如果通过同一语句调用该函数两次,它应该接收相同的 ID)。目前,用户总是必须LOCATION在调用点手动键入宏,如下所示:

#define S1(x) #x //voodoo to concat __FILE__ and __LINE__
#define S2(x) S1(x)
#define LOCATION __FILE__ S2(__LINE__)

do_stuff1(arguments, LOCATION)
do_stuff2(arguments, LOCATION)

如果我可以保存它们的输入,而不为每个函数创建一个宏,这样会更方便:

#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))

因此,我认为默认参数可以解决问题。有什么办法可以做到这一点?

4

3 回答 3

4

您似乎正在寻找std::experimental::source_location,这将是std::source_location未来的标准:

#include <experimental/source_location>

void print(std::experimental::source_location const& location
    = std::experimental::source_location())
{
    printf("hello %s:%d\n", location.file_name(), location.line());
}
于 2018-11-20T18:18:19.107 回答
2

__LINE__例中的宏扩展为 3

当然,因为您的函数声明是在第 3 行完成的,并且预处理器从那里扩展它。

另一个宏而不是函数声明可以很好地解决问题(取自@Ejay 的评论):

#define print() printf("hello %d\n", __LINE__)

在此处查看一个工作示例。

于 2018-11-20T18:21:30.210 回答
0

您可以编写一个将__FILE__and__LINE__插入参数列表的宏:

// Note: this doesn't work with a 0-argument function. Supporting 0-arg functions
// is much harder to do; I'd recommend just having a separate macro like as follows
#define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__)

#define LOCATED0(fn) fn(__FILE__, __LINE__)

void print(char const* file_name, int line)
{
    printf("hello %s:%d\n", file_name, line);
}

int do_something(int value, char const* file_name, int line);

int main() {
    LOCATED0(print);
    LOCATED(do_something, 42);
}

再做一些工作,您可以使它在呼叫站点看起来更好:

#define LOCATED(...) LOCATED_##__VA_ARGS__

void print(char const* file_name, int line)
{
    printf("hello %s:%d\n", file_name, line);
}
#define LOCATED_print() ::print(__FILE__, __LINE__)

int do_something(int value, char const* file_name, int line);
#define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__)

int main() {
    LOCATED(print());
    LOCATED(do_something(42));
}
于 2018-11-20T18:36:36.153 回答