但是,一个有点奇怪的问题是,如果我没有记错的话,C ++源代码不需要文件系统来存储其文件。
拥有一个可以通过照相机扫描手写纸的编译器将是一个符合要求的实现。尽管实际上没有太大意义。
但是,C ++ 20现在使用添加了源位置file_name。现在,这是否意味着源代码应始终存储在文件中?
C ++ 20功能std::source_location用于捕获有关调用函数的上下文的信息。当我尝试将其与可变参数模板函数一起使用时,遇到一个问题:我看不到放置source_location参数的地方。
以下操作无效,因为可变参数必须在末尾:
// doesn't work
template <typename... Args>
void debug(Args&&... args,
const std::source_location& loc = std::source_location::current());
Run Code Online (Sandbox Code Playgroud)
以下内容也不起作用,因为调用者将被介于两者之间的参数所困扰:
// doesn't work either, because ...
template <typename... Args>
void debug(const std::source_location& loc = std::source_location::current(),
Args&&... args);
// the caller will get confused
debug(42); // error: cannot convert 42 to std::source_location
Run Code Online (Sandbox Code Playgroud)
可以在可变参数模板中无缝使用的评论中告诉我std::source_location,但是我很难弄清楚该如何做。如何std::source_location与可变参数模板函数一起使用?
c++ default-arguments variadic-templates c++20 std-source-location
库基础知识的C++扩展,版本2(N4564)介绍了该类型std::experimental::source_location.
§14.1.2[reflection.src_loc.creation]说:
Run Code Online (Sandbox Code Playgroud)static constexpr source_location current() noexcept;返回:当函数调用(C++14§5.2.2)调用其后缀表达式(可能是带括号的)id-expression命名时
current,返回source_location带有实现定义值的a.该值应受#line(C++14§16.4)影响,其方式与__LINE__和__FILE__.如果以其他方式调用,则返回的值未指定.备注:当使用大括号或等于初始化程序来初始化非静态数据成员时,任何调用都
current应该对应于构造函数的位置或初始化成员的聚合初始化.[ 注意:当用作默认参数(C++14§8.3.6)时,该值
source_location将是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)}
{ …Run Code Online (Sandbox Code Playgroud) 考虑模板函数g()和自由函数f():
#include <iostream>
#include <source_location>
auto g(auto...) {
std::cout << std::source_location::current().column() << "\n";
}
auto f() {
std::cout << std::source_location::current().column() << "\n";
}
int main() {
g();
f();
}
Run Code Online (Sandbox Code Playgroud)
用GCC-trunk编译得到以下输出:
43
44
Run Code Online (Sandbox Code Playgroud)
为什么g()和f()产生不同的结果?我希望结果是一样的。为什么在模板实例化过程中单位偏移消失了?
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';
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,有关于的消息
expansion of [...] is not a constant expression
Run Code Online (Sandbox Code Playgroud)
关于这return std::integral_constant<int, location.line()>{}条线.有什么好处它是有方法source_location是constexpr,如果我不能使用它们?
c++ templates compile-time c++-experimental std-source-location
#include <stdio.h>
void print(int a = __LINE__){printf("hello %d\n", a);}
void main(){
print();
print();
print();
print();
}
Run Code Online (Sandbox Code Playgroud)
本例中的宏__LINE__扩展为 3,因此使用相同的值调用 print 函数 4 次。有没有办法说服编译器在调用点扩展此宏,以便使用 C++11 中存在的功能6,7,8,9而不是调用 print 函数?3,3,3,3
我的用例:
在我的应用程序中,我提供了多个采用唯一 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)
Run Code Online (Sandbox Code Playgroud)
如果我可以节省他们的打字时间,而不需要为每个函数创建宏,如下所示,那就更方便了:
#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))
Run Code Online (Sandbox Code Playgroud)
因此我认为默认参数可以解决问题。有什么办法可以实现这一点吗?