如何实现std :: experimental :: source_location?

时间:2015-12-21 23:08:48

标签: c++ reflection c++17 fundamentals-ts

库基础知识的C ++扩展,版本2 N4564)引入了类型std::experimental::source_location

§14.1.2[reflection.src_loc.creation]说:

static constexpr source_location current() noexcept;
     

返回:当由函数调用(C ++14§5.2.2)调用时, postfix-expression 是一个(可能是括号内的) id-表达式命名current,返回带有实现定义值的source_location。该值应受#line(C ++14§16.4)影响,其方式与__LINE____FILE__相同。如果以其他方式调用,则返回的值未指定。

     

备注:当使用 brace-or-equal-initializer 初始化非静态数据成员时,对current的任何调用都应对应于初始化成员的构造函数或聚合初始化的位置。

     

[注意:当用作默认参数时(C ++14§8.3.6),source_location的值将是{{1}的调用位置在呼叫站点。 - 结束记录]

如果我理解正确,那么该功能就像这样使用。

current

预期产出:

#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::experimental::source_location,它在内部使用THROW_WITH_SOURCE_LOCATION__FILE__宏来正确初始化异常对象。

我想知道图书馆如何实施__LINE__。除非我完全忽略了这一点,否则如果没有特殊的编译器支持,这样做是不可能的。但是需要什么样的魔术编译器功能才能使其工作?它是否可以与std::experimental::source_location部署的技巧相媲美?是否有可用于查看此功能的实验性实现?我查了the SVN sources for GCC但还没找到任何内容。

1 个答案:

答案 0 :(得分:7)

实现这一点需要编译器的支持。例如,with gcc,您可以使用built-ins functions之类的

   int __builtin_LINE()
     

此函数等效于预处理器__LINE__宏,并返回内置调用的行号。在函数F的C ++默认参数中,它获取对F的调用的行号。

   const char * __builtin_FUNCTION()
     

此函数等效于预处理器__FUNCTION__宏,并返回内置调用所在的函数名称。

   const char * __builtin_FILE()
     

此函数等效于预处理器__FILE__宏,并返回内置调用所在的文件名。在函数F的C ++默认参数中,它获取文件调用F的名称。