【问题标题】:Why can't I emplace ifstreams in a vector?为什么我不能在向量中放置 ifstreams?
【发布时间】:2013-06-09 23:41:26
【问题描述】:

以下示例程序不能为我编译 clang 3.1 或 gcc 4.8:

#include <fstream>
#include <vector>

using namespace std;

int main()
{
    vector<ifstream> bla;
    bla.emplace_back("filename");
    return 0;
}

但是,我认为 emplace_back 应该

"在向量的末尾插入一个新元素,紧随其后 当前最后一个元素。这个新元素是使用 args 作为其构造的参数。”

有谁知道为什么这不能编译?是我理解错了还是库实现还没有完成?

【问题讨论】:

  • 我不懂 C++,但你是否根据你的包含来判断你在 vector 处有错字。你的意思是矢量?如果我错了,请纠正我。
  • std::vector 的元素必须是可复制的,fstreams 不是。
  • ifstream 是在 fstream 包含中定义的有效类型。
  • 我尝试将您的 emplace_back() 更改为 push_back(std::move(foo)),而 GCC 4.7.3 给了我一个内部编译器错误并崩溃了。耶。
  • answer 提到在某些版本的 gcc 中,流类没有实现移动和交换操作。也许您的版本缺少支持?

标签: c++ c++11


【解决方案1】:

c++11 中的流是可移动的,所以理论上你应该可以做你想做的,问题是在 gcc/libstdc++ 中还没有实现可移动的流。

要进一步支持我的答案,请查看 gcc/libstdc++ c++11 状态: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2011

尤其是 27.5、27.8、27.9

【讨论】:

    【解决方案2】:

    这是std::basic_istream 的实现中的一个错误。它应该是可移动的,但不是;并且只有可移动类型可以存储在向量中。

    Here is the bug report against GCC.

    【讨论】:

    • 谢谢,这就解释了。即使它们不可移动,您是否也应该能够将可复制类型存储在向量中?
    • @dgel:流也不能复制(在 C++98 或 C++11 中都没有)。
    • @HighCommander4:我知道,但我在评论他的一般性声明,即“只有可移动类型可以存储在向量中”,这可能会造成混淆。
    • @dgel:可复制类型可移动的。 “可移动”意味着您可以创建与现有对象相同的对象(可能使现有对象无效); “可复制”意味着您可以在不更改现有对象的情况下执行此操作。
    • @Mike Seymour:谢谢,我认为可移动意味着它实现了移动语义,而可复制类型可能无法实现相关的移动相关功能。
    【解决方案3】:

    由于尚未修复 (AFAIK),这里有一个快速的解决方法:

    typedef std::shared_ptr<std::ifstream> SharedIFS;
    inline SharedIFS MakeIFS(const std::string &file) {
        return SharedIFS(new std::ifstream(file));}
    

    除非我错过了一些愚蠢的东西,否则 SharedIFS 应该是可移动和可复制的。与普通的 emplace_back 相比,它有一些开销,但至少您可以将它放入向量中。

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多