在 C++ 中加载文件的 constexpr 函数是否可行?

are constexpr functions that load files possible in C++?

有一个类似的问题 here 但它没有有价值的信息所以我想再问一次 - 是否可以使用 constexpr 函数加载任意文件的内容?我知道这似乎是不可能的,因为允许文件 I/O(fopenopen ...)的所有可能函数都不是 constexpr,因此在这种情况下无法调用。然而 - 因为这里有很多人关注 c++17 及以后的开发 - 是否有希望进一步的标准将包括一些文件 I/O API 将是 constexpr 和可以用于在编译时加载文件吗?

只是为了比较 - Haxe 允许通过编译时宏做几乎任何事情,所以在 C++ 中有类似的东西会很酷。例如,通过反序列化文件生成 class 个实例。

这是(至少对我而言)在不同语言之间切换时 over-complication 的典型案例。 是的,您可以实现将 compile-time 文件加载到 C++ 中的功能,我们也可以添加 runtime-reflection。但是在我看来,这些不是必需的,也不是想要的功能。

如果您有能力编写需要 constexpr 的程序,您可以理解 pre-build 事件的概念(使用 Microsoft 术语),如果您能够阅读文件,您应该有足够的能力编写代码来将文件解析为其他格式。

在这种情况下,compile-time 解决方案是编写一个 stand-alone 工具来解析有问题的文件,并生成一个包含所需文件的 .h (header) 文件常数和这些常数的评估。这个工具然后可以 运行 在你的 build-process 是 运行.

之前

这样你的 constexpr 就变成了常量表达式

以“程序版本号”为例,常见的解决方案是让开发人员 IDE 或 stand-alone 工具创建一个 header-file 包含常量值是软件的版本。

许多 FOSS 软件在其 ./configure 脚本中包含此类功能 - 从 Git 或类似的解析当前修订号 - 因此意味着软件的任何 built-version 都可以输出 build-number,允许问题跟踪。

简而言之 - 如果 c++17 或任何其他未来版本提供了你正在寻找的功能,我会 非常惊讶和失望 - 这样做增加了理解的要求file-system 的用户,并且只能成功实现最好留给最终用户的功能。

However, we should not fall into the trap of trying to add every possible feature to it in an attempt to please everyone.~ Bjarn Stroustrup

通俗地说,这就像销售 push-bike 以及 single-size 头盔和自行车短裤(法律要求用户使用)。它可能适合 大多数 用户的需求,但试图以我的腰围穿上所说的短裤会……有问题。

想象一下架构、嵌入式系统等之间的交叉编译器所增加的复杂性

[编辑/]

这可能不是一个完美的答案 - 并且在某种程度上是基于意见的;我试图提供的是一种理解,虽然可以说 大多数 用户是 desktop-oriented,但添加类似的东西会使嵌入式系统和其他应用程序的编译器开发变得非常复杂。而这正是 C++ 试图避免的。

Some light reading

[编辑 2/]

评论中指出“为什么不让编译器直接将 file-contents 添加为 char *,这是一个很好的问题!在这方面我有两点要提出.

  1. 您要在 constantexp 中解析 char* 吗?如果是这样,那么您将需要一个循环和变量 - 您无法可靠使用的东西。
  2. 如果您想要文件内容的字符串文字 - 它不是很漂亮,而是 C++ 的预处理器 can do this(假设 file-format 不包含无效字符)。

再一次 - 任何比这些简单示例 becomes complex enough to be hard 在标准 中定义更复杂的文件是否应该是二进制文件?应该是文字吗? line-endings 是什么?应该解析吗?

与此同时,您可以轻松 Use existing tools,甚至可以结合其他方法使用。 例如,编写一个工具来解析你的二进制文件,re-encode 它作为一系列转义序列(例如:[=15=]x0, [=15=]x12, [=15=]x22),让它自动添加到定义指针的 header 文件中到所说的数据。然后 #include 那 header - 你有你想要的,对于你工作的平台,并且没有可能在 C++ 标准中造成可能导致 inherent complexity.

的漏洞

请记住,在某些情况下,C++ 作为一种语言终于从 very-long 大量 Very Bad Press. And Compilers that to this day Still act totally-differently 中恢复过来。

在我看来,每个 C++ 程序员都想要一个世界,在那里我可以编写我的 "完美地 object 面向 C++ 代码一次" 然后它将 just work 从 1990 年代的 Nokia-phone 到最新的 quantum-optical-univac。 最终我们离这样做更近了一点,向更广阔的世界证明了 C++ 的价值。向 Java 发射我们的 death-star 光束,或类似的挑衅性言论。

因此,我说 - 这个想法很好,但是 not-needed。当然,如果你想写一个Full Proposal, outlining how you will avoid any issues that could hurt the future C++-Utopia, I would beg you to do so. If a feature like this can be done without hurting the pre-processor, platform independence, creating Impossibly complex errors,或者类似的。那你会比我聪明 - 因为我目前看不出那是怎么可能的。