无法分配或复制 iostream 对象?

发布于 2024-12-25 19:17:28 字数 608 浏览 1 评论 0原文

iostream 和其他流类实际上不是类,而是 typedef,对吧?

问题是,我尝试在初始化列表中初始化一个 istream 对象,但不幸的是我收到了一个错误,代码如下:

class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream ais;
};

无法使用 g++ 编译,错误:

synthesized method ‘std::basic_istream<char, std::char_traits<char> >::basic_istream(const std::basic_istream<char, std::char_traits<char> >&)’ first required here 

我搜索了,发现, iostream 无法分配或复制。但为什么我无法在初始化列表中初始化它呢?

因为我认为,初始化列表将调用对象的构造函数/复制构造函数,对吧?

iostream and other stream class are not actually class, but typedefs, right?

Here is the problem, I tried to initialize a istream object in initialization list, but unfortunately I got an error, code goes bellow:

class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream ais;
};

Can't compile with g++, error:

synthesized method ‘std::basic_istream<char, std::char_traits<char> >::basic_istream(const std::basic_istream<char, std::char_traits<char> >&)’ first required here 

I searched SO, found that, iostream cannot be assigned or copy. But why cannot I initialize it in the initialization list?

Cuz I think, the initialization list will invoke the object's constructor/copy-constructor, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

喜爱纠缠 2025-01-01 19:17:28

您的代码尝试将一个 istream(传递给构造函数的一个)转换为两个 istream(传递给构造函数的一个和 ais) >。 istream 对象代表实际的流本身。只有一个流,无法以某种方式将其变成两个流。

甚至还不清楚这意味着什么。如果流上有一些数据,那么首先读取的流是否会获取它?还是他们都明白了?如果是这样,谁或什么复制了它?

istream 就像一个文件本身。如果您不亲自将数据从一个文件复制到另一个文件,则无法将一个文件变成两个文件。但是,您可以根据需要拥有任意数量的指向同一 istream 的引用或指针。解决您问题的方法可能是让 ais 成为参考。

Your code attempts to turn one istream, the one passed to the constructor, into two istreams, the one that was passed to the constructor and ais. An istream object represents that actual stream itself. There is only one stream and there is no way to somehow turn it into two streams.

It's not even clear what that would mean. If there's some data on the stream, does whichever stream reads first get it? Or do they both get it? If so, who or what duplicates it?

An istream is like a file itself. You cannot turn one file into two files without copying the data from one to the other yourself. You can, however, have as many references or pointers to the same istream as you want. The solution to your problem is probably to make ais a reference.

巷雨优美回忆 2025-01-01 19:17:28

您将成员变量声明为:

istream ais;

意味着将在初始值设定项列表中调用复制构造函数。这不是特定于初始化列表的:您不能在任何地方执行此操作。

您可以将成员变量更改为引用:

istream& ais;

但这意味着您必须确保 ais 引用的 istreamA< 的生命周期内有效/代码>。

You have the member variable declared as:

istream ais;

meaning the copy constructor will be invoked in the initializer list. This is not specific to the initializer list: you can't do this anywhere.

You could change the member variable to be a reference:

istream& ais;

but that means you have to ensure that the istream to which ais refers is valid for the lifetime of A.

离线来电— 2025-01-01 19:17:28

iostream 和其他流类实际上不是类,而是 typedef,对吗?

是的,但这不相关。

但是为什么我无法在初始化列表中初始化它呢?

因为它既不能被复制,也不能被赋值。 Ctor init list 并不神奇。要从 is 创建 ais,您需要制作副本,但不能。

iostream and other stream class are not actually class, but typedefs, right?

Yes, but that's not relevant.

But why cannot I initialize it in the initialization list?

Because it can be neither copied nor assigned. Ctor init list is not magical. To create ais from is you need to make a copy, and you can't.

千纸鹤 2025-01-01 19:17:28

流对象表示数据流的句柄。抄袭是没有意义的。另外,仅复制流的基本部分并不是正确的做法:这将切掉有趣的部分(尽管您可以通过使用流缓冲区来获取实际有趣的部分)。

如果类包含流,则您要在类中初始化的是对该流的引用:

std::istream& ais;

当然,这意味着只要您正在使用流,某些外部就需要保持该流处于活动状态。如果这不是您想要或需要的,您可以让您的类保存例如 std::ifstream 并采用 std::string 作为构造函数参数:如果字符串非空则打开相应的文件。否则,您需要将流的 rdbuf() 设置为 std::cin 中的:

if (name.empty())
    ais.open(name.c_str());
else
    ais.rdbuf(std::cin.rdbuf());

The stream object represent a handle to streams of data. Copying that doesn't make sense. Also, this wouldn't be the right thing to copy only tge base part of a stream: this would be slicing off the interesting bit (although you could get hold of thr actually interesting portion by using the stream buffer).

What you want to initialize in your class if it holds a stream is a reference to the stream:

std::istream& ais;

Of course, this means that some external needs to keep the stream alive as long as you are using it. If this isn't what you want or need you can have your class hold e.g. an std::ifstream and take a std::string as constructor argument: if the string is non-empty you'd open the corresponding file. Otherwise you'd set your stream's rdbuf() to the one from std::cin:

if (name.empty())
    ais.open(name.c_str());
else
    ais.rdbuf(std::cin.rdbuf());
挽袖吟 2025-01-01 19:17:28

除了您已经得到的答案之外,您还可以使用传入的流的 streambuf 初始化 ais (根据您的定义)(当然,同样的警告与引用一样:您必须确保 Streambuf 保持有效,直到对象被破坏)。

使用底层 Streambuf 进行初始化可能是最接近复制流的方法:虽然两者仍然从同一文件读取并使用相同的缓冲(以及 Streambuf 可能执行的其他处理),但所有格式化和错误处理标志都是分开的。

要使用streambuf初始化ais,您可以编写:

class A 
{
public:
  A(std::istream& is = std::cin):
    ais(is.rdbuf())
  {
  }
private:
  std::istream ais;
};

In addition to the answers you already got, you can also initialize ais (as of your definition) with the streambuf of the stream you passed in (of course, the same caveat as with the reference applies: You must ensure that the streambuf stays valid until the object is destructed).

Initializing with the underlying streambuf is probably the closest to copying a stream you can do: While both still read from the same file and use the same buffering (and other processing the streambuf may do), all the formatting and error handling flags are separate.

To initialize ais with the streambuf, you write:

class A 
{
public:
  A(std::istream& is = std::cin):
    ais(is.rdbuf())
  {
  }
private:
  std::istream ais;
};
往日情怀 2025-01-01 19:17:28
class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream& ais;
};

请注意,该成员是引用类型。正如您所写的,您正在制作一个副本来初始化该成员。

class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream& ais;
};

Notice the member is a reference type. As you've written it, you're making a copy to initialize the member.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文