使用字符串作为模板参数时的编译意外

dma*_*ola 4 c++ c++20

我正在玩模板中的字符串。我阅读了一些有趣的博客并开始玩代码。

在下一个示例中,我能够在模板参数中传递字符串文字:

#include <algorithm>
#include <iostream>

template<size_t N>
struct StringLiteral {
    constexpr StringLiteral(const char (&str)[N]) {
        // commenting this makes the program to not compile
        std::copy_n(str, N, value);
    }
    constexpr size_t size() const
    {
        return N;
    }

    // changing N to literal, such as 10, makes the program to not compile
    char value[N];
};

template<StringLiteral lit>
void Print() {
    static constexpr auto size = lit.size();
    static constexpr auto contents = lit.value;

    std::cout << "Size: " << size << ", Contents: " << contents << std::endl;
}

int main()
{
    Print<"abc">();
}
Run Code Online (Sandbox Code Playgroud)

神箭链接

在此示例中,我Print通过模板参数传递一个字符串,它将打印大小和值。到目前为止,一切都很好。

然而,我正在使用一些我不完全理解的功能,这可能就是我如此困惑的原因。

  1. 如果我删除std::copy_n(),它就无法编译。这是非常令人惊讶的,因为该代码位于构造函数内部,是N之前推导出来的,所以我不确定为什么copy_n会有这些含义。
  2. 更改char value[N]char value[10]也会使程序无效。10 是一个文字,所以我希望编译器能够毫无问题地推导出它。

你能澄清一下发生了什么事吗?

Hol*_*Cat 5

这两个错误都是由于value部分未初始化而引起的。默认情况下将{}所有元素添加为零是解决此问题的一种方法:char value[N]{};