在C++中连接__FILE__和__LINE__宏

43
我希望我的异常信息包含有关异常位置的信息。
因此,我想要像这样的东西:
#define LOCATION __FILE__ " : " __LINE__

throw std::exception(std::string("ABCD. ") + LOCATION);

那个定义显然是错误的。我该如何实现这个?


1
注意:您可以将异常构造简化为 std::exception("ABCD." LOCATION) - Daniel Frey
你可以在此处查看:https://dev59.com/93I-5IYBdhLWcg3wqqTh - Barath Ravikumar
1个回答

74

你需要将该宏展开两层:

#define S1(x) #x
#define S2(x) S1(x)
#define LOCATION __FILE__ " : " S2(__LINE__)

原因在这里:

在将#x传递之前,您需要将__LINE__扩展两个级别。

首先,在函数式宏中使用运算符#时,必须跟随宏参数,但__LINE__不是参数,因此编译器会抱怨它是一个杂项运算符。

另一方面,__LINE__本身是一个宏,包含当前行号,应该在使用#之前将其扩展为数字,否则你会得到字符串"__LINE__"而不是数字。

S2(__LINE__)__LINE__扩展为行号,然后我们将行号传递给#x


2
如果我想将__PRETTY_FUNCTION__作为第三个添加怎么办?提前致谢! - uss
5
如果您不想自己创建宏S1和S2,Boost的BOOST_PP_STRINGIZE(__LINE__)可以实现这一点。它会将__LINE__转换为一个字符串。 - AndiDog
1
@sree: #define LOCATION std::string(PRETTY_FUNCTION) + " :: " + std::string(FILE) + ":" + std::string(S2(LINE)) - adiog
@adiog虽然OP要求一个用于函数的异常字符串,但是你在这里提出的建议会导致错误:char foo[] = LOCATION;无论是在文件作用域还是在函数中。 - harper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接