c++ - 编译时检查 sizeof...(args) 是否匹配 constexpr 函数的结果

标签 c++ c++14 constexpr sfinae

我有 constexpr 函数来计算占位符的数量 https://godbolt.org/g/JcxSiu ,

例如:“你好 %1”返回 1,而“你好 %1,时间是 %2”返回 2

然后我想创建一个函数,如果参数的数量不等于占位符的数量,它就不会编译。

template <typename... Args>
 inline std::string make(const char* text, Args&&... args) {
   constexpr static unsigned count = sizeof...(args);

   // TODO how to compile time check if count == count_placeholders(text)    
  // constexpr static auto np = count_placeholders(text);

  //static_assert(count == np;, "Wrong number of arguments in make");

  return std::to_string(count);
};

这样 make("Hello %1", "World");编译并

make("Hello %1 %2", "World");make("Hello %1", "World", "John");没有。

我觉得可以,就是不知道怎么做。也许有一些模板魔法 :)

编辑

我几乎得到了我想要的。 https://godbolt.org/g/Y3q2f8

现在在 Debug模式下中止。有可能编译时出错吗?

最佳答案

我的第一个想法是使用 SFINAE 启用/禁用 make();像

template <typename... Args>
auto make(const char* text, Args&&... args)
   -> std::enable_if_t<sizeof...(args) == count_placeholders(text),
                       std::string>
 {
    // ... 
 }

不幸的是,这没有编译,因为 text 不能在 constexpr 中使用。

但是,如果您接受 text 是一个模板参数(在编译时已知),您可以做一些事情

template <char const * const text, typename ... Args>
auto makeS (Args && ... args)
   -> std::enable_if_t<sizeof...(args) == count_plc(text), std::string>
 { return std::to_string(sizeof...(args)); }

下面是一个完整的工作示例

#include <string>
#include <type_traits>

constexpr std::size_t count_plc (char const * s,
                                 std::size_t index = 0U,
                                 std::size_t count = 0U)
 {
   if ( s[index] == '\0' )
      return count;
   else if (    (s[index] == '%')  && (s[index+1U] != '\0')
             && (s[index+1U] > '0') && (s[index+1U] <= '9') )
      return count_plc(s, index + 1U, count+1U);
   else
      return count_plc(s, index + 1U, count); 
 }

template <char const * const text, typename ... Args>
auto makeS (Args && ... args)
   -> std::enable_if_t<sizeof...(args) == count_plc(text), std::string>
 { return std::to_string(sizeof...(args)); }

constexpr char const h1[] { "Hello %1" };
constexpr char const h2[] { "Hello %1 %2" };

int main ()
 {
   makeS<h1>("World"); // compile
   //makeS<h2>("World"); // compilation error
   //makeS<h1>("World", "John"); // compilation error
 }

关于c++ - 编译时检查 sizeof...(args) 是否匹配 constexpr 函数的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46730950/

相关文章:

C++ MFC 缺少 const char* 变量

c++ - 通过通用 lambda 理解 Y Combinator

c++ - static, constexpr, const - 它们一起使用时是什么意思?

c++ - 在重载解析期间调用转换运算符而不是转换 C++17 中的构造函数

c++ - 使用 Clang 的模板和 lambda 的编译错误

c++ - 寻求对 constexpr 功能的澄清

c++ - 格式错误,无需诊断 (NDR) : ConstExpr Function Throw in C++14

c++ - Visual Studio 2015 rc中从模板类派生的类的构造函数继承

c++ - gstreamermm和Qt编译错误

c++ - 简单的指针问题(我不知道为什么我没有得到确切的解释)