簡體   English   中英

編譯時檢查sizeof…(args)是否與constexpr函數的結果匹配

[英]Compile time check if sizeof…(args) matches result from constexpr function

我有constexpr函數,該函數計算占位符的數量https://godbolt.org/g/JcxSiu

例如:“ Hello %1 ”返回1 ,而“ Hello %1, time is %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"); 才不是。

我想可以做到的,我只是不知道怎么做。 也許與一些模板magick :)

編輯

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

現在以調試模式中止。 是否有可能使編譯時出錯?

我的第一個想法是使用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
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM