std :: experimental :: source_location如何实现? [英] How could std::experimental::source_location be implemented?
问题描述
图书馆基础知识的C ++扩展版本2 ( N4564 )引入了 std :: experimental :: source_location
。
C++ Extensions for Library Fundamentals, Version 2 (N4564) introduces the type std::experimental::source_location
.
§14.1.2[reflection.src_loc.creation]说:
§ 14.1.2 [reflection.src_loc.creation] says:
static constexpr source_location current() noexcept;
返回值:由函数调用调用时(C ++ 14§ 5.2.2)其 postfix-expression 是(可能带有括号的) id-expression 命名为 current
,返回一个 source_location
具有实现定义的值。该值应受 #line
(C ++ 14§16.4)的影响,方式与 __ LINE __
相同,并且 __ FILE __
。如果以其他方式调用,则返回的值是不确定的。
Returns: When invoked by a function call (C++14 § 5.2.2) whose postfix-expression is a (possibly parenthesized) id-expression naming current
, returns a source_location
with an implementation-defined value. The value should be affected by #line
(C++14 § 16.4) in the same manner as for __LINE__
and __FILE__
. If invoked in some other way, the value returned is unspecified.
备注:当括号或相等的初始化程序用于初始化非静态数据成员,对 current
的任何调用应对应于构造函数或用于初始化该成员的聚合初始化的位置。
Remarks: When a brace-or-equal-initializer is used to initialize a non-static data member, any calls to current
should correspond to the location of the constructor or aggregate initialization that initializes the member.
[注意:当用作默认参数(C ++ 14§8.3.6)时, source_location的值
将是呼叫站点上当前
的呼叫位置。 — 尾注]
[ Note: When used as a default argument (C++14 § 8.3.6), the value of the source_location
will be the location of the call to current
at the call site. — end note ]
如果我理解正确,则该功能应按以下方式使用。
If I understand correctly, then the feature is intended to be used like this.
#include <experimental/source_location> // I don't actually have this header
#include <iostream>
#include <string>
#include <utility>
struct my_exception
{
std::string message {};
std::experimental::source_location location {};
my_exception(std::string msg,
std::experimental::source_location loc = std::experimental::source_location::current()) :
message {std::move(msg)},
location {std::move(loc)}
{
}
};
int
do_stuff(const int a, const int b)
{
if (a > b)
throw my_exception {"a > b"}; // line 25 of file main.cxx
return b - a;
}
int
main()
{
try
{
std::cout << do_stuff(2, 1) << "\n";
}
catch (const my_exception& e)
{
std::cerr << e.location.file_name() << ":" << e.location.line() << ": "
<< "error: " << e.message << "\n";
}
}
预期输出:
main.cxx:25: error: a > b
没有 std :: experimentalal :: source_location
,我们可能已经使用了一个辅助宏 THROW_WITH_SOURCE_LOCATION
,该宏在内部使用了 __ FILE __
和 __LINE __
宏正确地初始化异常对象。
Without std::experimental::source_location
, we might have used a helper macro THROW_WITH_SOURCE_LOCATION
that internally makes use of the __FILE__
and __LINE__
macros to initialize the exception object properly.
我想知道库如何实现 std :: experimental: :source_location
。除非我完全遗漏了要点,否则没有特殊编译器支持就不可能这样做。但是,需要什么样的魔术编译器功能才能实现此目的?它可以与 std :: initializer_list
部署的技巧相提并论吗?是否有实验性的功能可以查看?我已经检查了 GCC的SVN来源
I was wondering how a library could implement std::experimental::source_location
. Unless I'm completely missing the point, doing so is not possible without special compiler support. But what kind of magic compiler features would be needed to make this work? Would it be comparable to the trick deployed for std::initializer_list
? Is there any experimental implementation of this feature available to look at? I have checked the SVN sources for GCC but didn't find anything yet.
推荐答案
要实现这一点,将需要编译器的支持。例如,与gcc 一起使用,您可以使用< a href = https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html rel = noreferrer>内置函数,例如
Implementing this will require support from the compiler. For instance, with gcc, you could possibly use built-ins functions like
int __builtin_LINE()
此函数等效于预处理器 __ LINE __
宏,并返回内置调用的行号。在函数 F
的C ++默认参数中,它获取对 F
的调用的行号。
This function is the equivalent to the preprocessor __LINE__
macro and returns the line number of the invocation of the built-in. In a C++ default argument for a function F
, it gets the line number of the call to F
.
const char * __builtin_FUNCTION()
此函数等效于预处理器 __ FUNCTION __
宏,并返回调用内置函数的函数名称。
This function is the equivalent to the preprocessor __FUNCTION__
macro and returns the function name the invocation of the built-in is in.
const char * __builtin_FILE()
此函数等效于预处理器 __ FILE __
宏,并返回调用内置函数的文件名。在C ++的默认参数中函数 F
,它将获取对 F
的调用的文件名。
This function is the equivalent to the preprocessor __FILE__
macro and returns the file name the invocation of the built-in is in. In a C++ default argument for a function F
, it gets the file name of the call to F
.
这篇关于std :: experimental :: source_location如何实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!