C++ 初始化固定宽度的 std::string 数组中的每个字符

问题描述

有没有办法使用值初始化而不是 std::array 或循环分配文字来初始化 std::string 的数组(普通或 std::transform())中每个字符串的每个字符还是临时对象?以一个 20 std::string 数组为例,每个 20 字符我们想将每个字符初始化为 'x'

本质上,我想做的是将每个字符串初始化为 std::string(WIDTH,char)。初始化第一个很简单,例如

#define NSTR  20
#define NCHR  20
...
std::string strarr[NSTR] { std::string(NCHR,'x') };

但是在第一个字符串的初始值设定项列表中只提供了一个初始值设定项,由于提供的值少于所有值,其余字符串按预期被初始化为空。通过值、直接、复制或列表 Initialization 似乎没有提供通过初始化的方法。 (我试图避免为数组中的每个字符串提供明确的文字或临时的,例如,如果 NSTR1000,这会导致空间问题,NCHR1000 也是如此{1}})

创建/构造对象后,循环并分配临时(或文字)或std::transform(或std::fill)提供了一种简单的方法,例如

    std::string strarr[NSTR] {};
    
    for (auto& s : strarr) {
        s = std::string(NCHR,'x');
    }

    std::transform (strarr,strarr + NSTR,strarr,[](std::string s) { return s = std::string(NCHR,'x'); } );

或者最短的,使用 std::fill_n一个临时字符串对象:

    std::fill_n (strarr,NSTR,std::string (NCHR,'x'));

std::string 使用容器似乎不会暴露任何额外的单次初始化,这些初始化也会初始化所有字符串,例如

    std::array<std::string,NSTR> strarr{};

是否有一些直接的方法来初始化 std::string 数组中的每个字符,还是在定义数组之后设置它们?如果是(或不是),为什么?

(我怀疑是后者,因为在评估初始化程序时 strarr 不是一个完整的实例,从而阻止使用该实例的迭代器。但是,在阅读了 {{ 的最新草稿后3}} 对于 C++20 标准,我找不到说你不能的部分或说你可以的部分——或者我只是对白话不够熟悉,无法识别相关部分...)

解决方法

使用立即调用的初始化 lambda:

#include <array>
#include <string>

constexpr std::size_t NSTR{20u};
constexpr std::size_t NCHR{20u};

int main() {


    const auto strarr = []() {
        std::array<std::string,NSTR> strings{};
        for(auto& s : strings) {
            s = std::string(NCHR,'x');
        }
        return strings;
    }(); //Immediately Invoked Initializing Lambda

    return 0;
}

IIIL's 通常用于变量的初始化,否则将是一个复杂的过程。这也使得变量现在可以声明为 const,而之前由于通过循环进行声明后初始化(const 所有的事情!)。