c++ - 捕获函数参数中的常量表达式

标签 c++ c++14 constexpr

出于各种原因,我正在寻找一种方法来捕获传递给函数的参数的常量表达式。解释起来有点棘手,所以我认为代码最好地展示了我想要实现的目标

#include <vector> // For std::size_t
#include <cstdio>

namespace
{
  template<std::size_t N, typename ...TArgs>
  constexpr int cstrlen (char const (&s) [N], std::size_t i = 0) noexcept
  {
    return i < N && s[i] != 0
      ? 1 + cstrlen (s, i + 1)
      : 0
      ;
  }

  template<std::size_t N, typename ...TArgs>
  inline void silly_printf (char const (&format) [N], TArgs && ...args) noexcept
  {
    static_assert (cstrlen (format) > 0, "format must not be empty string");
    printf (format, std::forward<TArgs> (args)...);
  }

}

#define SILLY_PRINTF(format, ...)                                           \
  static_assert (cstrlen (format) > 0, "format must not be empty string");  \
  printf (format, ##__VA_ARGS__);

int main()
{
  // This works but relies on macros
  SILLY_PRINTF ("Hello: %d", 1);

  // This doesn't work
  silly_printf ("Hello: %d", 1);
  return 0;
}

我无法让 silly_printf 按我希望的方式工作。编译器提示该表达式的计算结果不是常量。当使用字符串文字调用 silly_print 时,我们知道它是 constexpr,但 constexpr 性会丢失(顺便说一下,我在这里使用 VS2015)。

我想也许我可以将 constexpr 添加到参数中(很像 const),但没有成功。

我可以使用宏来解决这个问题(由 SILLY_PRINTF 宏演示),但这感觉像是失败。

欢迎任何想法。

PS。我真正想要实现的目标是稍微不那么愚蠢

最佳答案

有一个 GNU 扩展(由 g++ 和 clang 支持),允许用户定义以下形式的文字:

template<typename CharT, CharT... Chars>
constexpr void operator"" _something() { }

有了这个,我们可以构建一个没有宏的 constexpr-string 类型,可以像这样使用:

constexpr auto str = "testing\0length"_string;
static_assert(str.strlen() == 7, "!");

通过将字符串的所有属性编码到类型中,您可以在任何地方对其进行 static_assert,无论是否为 constexpr。 例如,在你的silly_printf中:

template<typename CharT, CharT... Chars, typename... Args>
void silly_printf(const constexpr_string<CharT, Chars...>& format_string, Args&&... args) {
    static_assert(format_string.strlen() > 0, "format string must not be empty");
    printf(format_string.c_str(), args...);
}

并像这样使用它:

silly_printf("testing %d %s %x embedded\0null"_string, 1, "2", nullptr);

您还可以使用另一个返回函数对象的运算符""_silly_printf()来获取类似"format string"_silly_printf(args...)的语法。

See it live on Coliru

关于c++ - 捕获函数参数中的常量表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33002279/

相关文章:

c++ - 检查 vector 中具有特定条件的唯一元素

c++ - 关于循环中值钳位的优化建议

c++ - 将 `hana::string` 转换为 `constexpr const char (&)[]`

c++ - 用标准库(静态)编译静态库链接

c++ - std shared_pointer_cast 未定义

c++ - 简单的复制和 move 操作有什么不同吗?

c++ - 可以比较 std::type_info 上的指针是否在常量表达式中相等?

c++ - g++-7.0/访问硬件中 constexpr 函数的不同行为

c++ - 从自定义链接列表打印值时陷入无限 while 循环

c++ - 为什么 SQLite 不让我查询特定的 ATTACHED 数据库?