8

std::experimental::source_location可能会在某个时候添加到 C++ 标准中。我想知道是否可以将位置信息放入编译时领域。本质上,我想要一个从不同源位置调用时返回不同类型的函数。像这样的东西,虽然它没有编译,因为location对象不是constexpr函数参数:

#include <experimental/source_location>

using namespace std::experimental;

constexpr auto line (const source_location& location = source_location::current())
{
  return std::integral_constant<int, location.line()>{};
}

int main()
{
  constexpr auto ll = line();
  std::cout << ll.value << '\n';
}

这不会编译,并带有关于的消息

expansion of [...] is not a constant expression

关于return std::integral_constant<int, location.line()>{}线。如果我不能使用它们,那么拥有这些方法source_location有什么好处?constexpr

4

1 回答 1

8

正如贾斯汀指出的那样,您的代码的问题是函数参数不是 constexpr,但是在 constexpr 中提到了以更有用的方式在 constexpr 函数中使用 source_location 的问题!功能提案说:

“Library Fundamentals v. 2” TS 包含一个“神奇的”source_location 类,可以获取类似于FILELINE宏以及func变量的信息(请参阅 N4529 了解当前草案,以及 N4129 了解一些设计说明)。不幸的是,因为 source_location 的“值”在 source_location::current() 被调用时被冻结,使用这个魔术类编写代码是很棘手的:通常,想要跟踪其调用点的函数必须添加一个默认参数如下:

void my_log_function(char const *msg,
                     source_location src_loc
                        = source_location::current()) {
  // ...
}

这个习惯用法确保 source_location::current() 调用的值是在 my_log_function 被调用的地方而不是它被定义的地方采样的。

但是,立即(即 constexpr!)函数在编译过程和 constexpr 评估过程之间建立了清晰的分离(另请参见 P0992)。因此,我们可以使 source_location::current() 成为立即函数,并根据需要将其包装在其他立即函数中:生成的值将对应于“根”立即函数调用的源位置。例如:

constexpr! src_line() {
  return source_location::current().line();
}

void some_code() {
  std::cout << src_line() << '\n';  // This line number is output.
}

所以这是目前一个悬而未决的问题。

于 2018-10-24T21:00:40.193 回答