You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC4.4.7下将ifstream存入std::map编译失败求助

问题:GCC 4.4.7下无法将std::ifstream存入std::map

我希望将std::ifstream对象存入std::map以便后续读取文件内容,但使用不支持C++11的旧版GCC 4.4.7编译代码时无法通过。

示例代码

#include <iostream>
#include <fstream>
#include <map>

int main()
{
    std::map<std::string, std::ifstream> DicoRCALbin;
    DicoRCALbin["a"] = std::ifstream("M3-6I_10.rcal_0001.bin", std::ios_base::binary);
}

编译报错信息(中文翻译)

$ g++ problem.cpp
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ios:39,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream:40,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iostream:40,
                 from test.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/ios_base.h: 在成员函数‘std::basic_ios<char, std::char_traits<char> >& std::basic_ios<char, std::char_traits<char> >::operator=(const std::basic_ios<char, std::char_traits<char> >&)’中:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/ios_base.h:793: 错误: ‘std::ios_base& std::ios_base::operator=(const std::ios_base&)’是私有的
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd:47: 错误: 在该上下文中
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd: 在成员函数‘std::basic_istream<char, std::char_traits<char> >& std::basic_istream<char, std::char_traits<char> >::operator=(const std::basic_istream<char, std::char_traits<char> >&)’中:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd:53: 注意: 首次需要合成方法‘std::basic_ios<char, std::char_traits<char> >& std::basic_ios<char, std::char_traits<char> >::operator=(const std::basic_ios<char, std::char_traits<char> >&)’在此处
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd: 在成员函数‘std::basic_ifstream<char, std::char_traits<char> >& std::basic_ifstream<char, std::char_traits<char> >::operator=(const std::basic_ifstream<char, std::char_traits<char> >&)’中:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd:81: 注意: 首次需要合成方法‘std::basic_istream<char, std::char_traits<char> >& std::basic_istream<char, std::char_traits<char> >::operator=(const std::basic_istream<char, std::char_traits<char> >&)’在此处
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/streambuf: 在成员函数‘std::basic_filebuf<char, std::char_traits<char> >& std::basic_filebuf<char, std::char_traits<char> >::operator=(const std::basic_filebuf<char, std::char_traits<char> >&)’中:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/streambuf:778: 错误: ‘std::basic_streambuf<_CharT, _Traits>& std::basic_streambuf<_CharT, _Traits>::operator=(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]’是私有的
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd:78: 错误: 在该上下文中
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd: 在成员函数‘std::basic_ifstream<char, std::char_traits<char> >& std::basic_ifstream<char, std::char_traits<char> >::operator=(const std::basic_ifstream<char, std::char_traits<char> >&)’中:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iosfwd:81: 注意: 首次需要合成方法‘std::basic_filebuf<char, std::char_traits<char> >& std::basic_filebuf<char, std::char_traits<char> >::operator=(const std::basic_filebuf<char, std::char_traits<char> >&)’在此处
test.cpp: 在函数‘int main()’中:
test.cpp:8: 注意: 首次需要合成方法‘std::basic_ifstream<char, std::char_traits<char> >& std::basic_ifstream<char, std::char_traits<char> >::operator=(const std::basic_ifstream<char, std::char_traits<char> >&)’在此处
[...]

原因分析

C++11标准之前,std::ifstream是不可拷贝的类型:它的拷贝构造函数和赋值运算符都被声明为私有。而代码中使用map::operator[]时,会先默认构造一个空的std::ifstream对象插入到map中,再尝试将临时创建的std::ifstream对象赋值给它,这一过程触发了被禁用的拷贝赋值操作,导致编译报错。

解决方案

方案1:存储指针而非对象

指针是可拷贝的类型,将map的value类型改为std::ifstream*,通过动态分配对象来存储:

#include <iostream>
#include <fstream>
#include <map>

int main()
{
    std::map<std::string, std::ifstream*> DicoRCALbin;
    // 动态创建ifstream对象并插入map
    DicoRCALbin["a"] = new std::ifstream("M3-6I_10.rcal_0001.bin", std::ios_base::binary);
    
    // 使用后记得释放内存,避免泄漏
    for (std::map<std::string, std::ifstream*>::iterator it = DicoRCALbin.begin(); it != DicoRCALbin.end(); ++it) {
        delete it->second;
    }
}

方案2:使用insert直接构造对象(需注意兼容性)

如果GCC 4.4.7支持在insert中直接构造std::pair,可以直接在map中构造std::ifstream对象,跳过默认构造和赋值的步骤:

#include <iostream>
#include <fstream>
#include <map>
#include <utility>

int main()
{
    std::map<std::string, std::ifstream> DicoRCALbin;
    // 直接构造pair并插入,避免赋值
    DicoRCALbin.insert(std::pair<std::string, std::ifstream>(
        "a", 
        std::ifstream("M3-6I_10.rcal_0001.bin", std::ios_base::binary)
    ));
}

注意:由于C++11前没有移动语义,部分旧编译器可能仍然无法通过这种方式编译,此时方案1会更稳妥。


内容的提问来源于stack exchange,提问作者lucd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 18:17:10