gcc 尝试输出属于结构成员的标准数组的元素时出错

gdrx4gfi  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(130)

下面的代码是如何运行的?

#include <iostream>
#include <array>

struct newperson {
    std::array<char, 20> name{};
    int age;
};

int main() {
    newperson nicolas = {
        "Nicolas",
        21
    };

    newperson martin = {
        "Martin",
        45
    };

    std::cout << nicolas.age << std::endl;
    std::cout << martin.name << std::endl;
    return 0;
}

,这是一个结构示例。
我收到以下错误:

bast.cpp: In function 'int main()':
bast.cpp:21:19: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::array<char, 20>')
   21 |         std::cout << martin.name << std::endl;
      |         ~~~~~~~~~ ^~ ~~~~~~~~~~~
      |              |              |
      |              |              std::array<char, 20>
      |              std::ostream {aka std::basic_ostream<char>}

C:/msys64/mingw64/include/c++/12.2.0/ostream:754:5: error: no type named 'type' in 'struct std::enable_if<false, void>'

是否需要一些不同的语法?我确实采用了一个现有的例子,并将C样式数组更改为标准数组。
如果我注解掉Martin行,我会得到以下内容:

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text+0x42): undefined reference to `std::ostream::operator<<(int)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text+0x54): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text+0x76): undefined reference to `std::ios_base::Init::~Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.text+0xa9): undefined reference to `std::ios_base::Init::Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.rdata$.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_[.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_]+0x0): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccClI6JG.o:bast.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout]+0x0): undefined reference to `std::cout'
collect2.exe: error: ld returned 1 exit status

不过,这似乎是mingw/msys 2的一个问题,因为它可以与Godbolt和www.example.com一起使用tio.run

huwehgph

huwehgph1#

对于std::array容器,无论元素类型如何,都没有重载的<<(流输出)运算符。但是,该数组容器确实有一个.data()成员,它产生指向第一个元素的指针;在您的例子中,这将是一个char*,并且用于输出char*的相关专门化(假设指向一个以空值正确终止的字符串/数组)将完成您想要的任务:

std::cout << martin.name.data() << std::endl;

但是,正如在注解中指出的,在这里使用std::string会更好,除非有特定的原因需要在结构中使用固定长度的数组。
(If您从使用.name成员的“C样式”数组(即char name[20];)的代码中修改了这个数组,那么<<将工作,因为该数组名将 * 自动 *“衰减”为指向其第一个元素的指针;对于std::array则不会发生这种情况。)
或者,尽管标准库没有为array<char, N>容器提供<<ostream重载,但您 * 可以 * 提供自己的重载。这可以作为函数模板实现(以便使用不同的数组大小),如下所示:

template <size_t N>
std::ostream& operator << (std::ostream& os, std::array<char, N> ArrChar)
{
    return os << ArrChar.data();
}

相关问题