【问题标题】:How define array of blanks of C++ compile time defined length?如何定义 C++ 编译时定义长度的空白数组?
【发布时间】:2017-07-21 13:15:49
【问题描述】:

我想定义一个 ASCII 空白字符串(字符数组),与一些静态 const int 或宏完全一样。我希望它发生在编译时,而不是运行时。

例如,如果

static const int numBlanks = 5

然后

char foo[] = "     " 

(五个空格)

如果

numBlanks = 3 

然后

char foo[] = "   " 

(三个空格)

等等。 (为什么?我想将它与strstr() 一起使用来定位至少为numBlanks 的序列,而numBlanks 可在编译时设置。)

是的,您可以使用 newmemset()/0,但我想在编译时执行一次,而不是在运行时一次又一次地执行。

是的,我可以接近

char foo[] = "                        "; 
foo[numBlanks] = '\0'; 

以及注释或assert() 以确保numBlanks 永远不会大于foo 的编译长度。

但是我可以在编译时完成这一切吗?定义一个长度为 numBlanks 的所有空格的 char 数组,其中 numBlanks 是 C++ 静态 const int 还是宏?

【问题讨论】:

  • 您可以使用配置脚本创建一个头文件来定义具有所需长度的变量吗?
  • 感谢@Barmar 进行代码编辑。另外,我没有提到 numBlanks 总是相当小,比如说在 2 到 10 的范围内。是的,我想我可以,但我不知道它是否值得这么多的努力和复杂性。
  • 您可以使用 C 预处理器。见stackoverflow.com/questions/8551418/…

标签: c++ arrays variables char compile-time


【解决方案1】:

我通过一些实验发现你可以在 c++14 或更高版本中使用更强大的 constexpr 语句来做到这一点。在这种情况下使用递归模板。

#include <cstdio>
#include <array>

template<size_t arrsize, size_t setnum>
constexpr void initVal(std::array<char, arrsize> &tmp) {
   std::get<setnum>(tmp) = ' ';
   if (setnum) initVal<arrsize, setnum ? setnum - 1 : 0>(tmp);
}

template<size_t arrsize>
constexpr auto initArray() -> std::array<char, arrsize> {
   std::array<char, arrsize> tmp{};
   std::get<arrsize - 1>(tmp) = '\0';
   initVal<arrsize, arrsize - 2>(tmp);
   return tmp;
}

constexpr std::array<char, 5 + 1> globalArr = initArray<5 + 1>();

int main()
{
   puts(globalArr.data());
}

【讨论】:

    【解决方案2】:

    这是一种使用可变参数模板和std::make_index_sequence的方法:

    #include <utility>
    
    template<typename T> struct blank_array;
    template<std::size_t... Is>
    struct blank_array<std::integer_sequence<std::size_t, Is...>> {
        static constexpr char arr[] = {(Is, ' ')..., '\0'};
    };
    template<std::size_t... Is>
    constexpr char blank_array<std::integer_sequence<std::size_t, Is...>>::arr[];
    
    template<std::size_t N>
    constexpr const char (&blanks)[N+1] =
        blank_array<std::make_index_sequence<N>>::arr;
    

    示例用法:

    #include <iostream>
    
    int main()
    {
        std::cout << "[" << blanks<5> << "]\n";
    }
    

    【讨论】:

      【解决方案3】:

      谢谢大家。我对你的一些回复投了赞成票并将其标记为答案。

      我想我希望得到一些更简单的东西。这不是世界上最重要的编程要求;我只是想也许我错过了一种直接的方法。你的回答太棒了!

      我决定最简单的方法是扭转问题:让编码器指定一个所需长度的字符串并从中得出长度:

      // Fill the following blanks array to a length equal to the minimum number of blanks to find (minimum 2)
      //                            12345678901234567890
      static const char blanks[] = "     ";
      static const int numBlanks = sizeof(blanks)-1;
      

      【讨论】:

        猜你喜欢
        • 2011-03-24
        • 1970-01-01
        • 2012-10-29
        • 1970-01-01
        • 2019-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多