【问题标题】:How to convert streamsize to other or how to pass streamsize value to vector?如何将流大小转换为其他或如何将流大小值传递给向量?
【发布时间】:2018-11-24 14:52:52
【问题描述】:

我有一个问题,我需要将流大小值传递给向量。如果我没有将它传递给固定大小。它将使用带有千元素的 emplace_back 开销。错误编译器可能导致数据丢失。

ifstream input(i_inputFilePath, ios::binary);
if (input.is_open())
{
    ofstream output(o_outputFilePath, ios::binary);
    std::array<char, 1024> buffer;
    while (true) {
        input.read(buffer.data(), buffer.size());
        streamsize dataSize = input.gcount();
        if (dataSize) 
        {
            std::vector<char> data(dataSize); // here the problem
            for (DWORD i = 0; i < dataSize; i++)
            {
                data.emplace_back(buffer[i]);
            }
            std::rotate(data.begin(), data.begin() + 1, data.end());
            output.write(data.data(), dataSize);    
        }
        else 
        { 
            output.close();
            input.close();
            break;
        }   
    }
}
else
{
    cout << "File is not exist";
}

【问题讨论】:

标签: c++ windows visual-studio


【解决方案1】:

如果您将单个整数参数传递给std::vector 的构造函数(如std::vector&lt;char&gt; data(dataSize);),将默认构造其中的许多元素,其大小将是传递的整数。

如果你然后emplace_back 进入它,它会增加它的大小,而不是覆盖已经构建的元素。

如果你想emplace_back你所有的元素,只需这样做,不需要将最终大小传递给构造函数:

std::vector<char> data;

std::vector 的大多数实现不会在每个 emplace_back 上重新分配,但会例如每次空间用完时将分配的空间加倍。因此,平均而言,这不会真的那么糟糕。

如果您担心重新分配,那么您可以强制向量预先分配空间

data.reserve(dataSize);

这实际上不会构造任何元素,但会确保提前分配必要的空间。

如果您收到关于从std::streamsize 转换为std::size_t 的错误消息,那么这是误报,因为在这种特殊情况下,您知道dataSize 只能具有范围为0 的值到1024。编译器正确地警告dataSize 的类型是有符号的,因此可能持有一个不能用无符号std::size_t 表示的负值。

你可以用类似的东西来测试这个假设是否正确

streamsize dataSize = input.gcount();
if(dataSize < 0 || dataSize > buffer.size()) {
    throw std::range_error("dataSize has unexpected value!");
}
data.reserve(static_cast<std::size_t>(dataSize));    

这确保dataSize 不会意外地为负数或大于预期值(如果是,它将抛出异常),否则它将提示编译器您确实想使用显式强制转换进行缩小转换,这应该抑制警告/错误消息。

【讨论】:

  • 我知道,但它一直在调整大小。如果 100 万个元素保持调整大小为 1 以适应,它将产生开销。如果我知道缓冲区大小,为什么向量需要保持调整大小?
  • streamsize dataSize 不想允许转换的问题。与 data.reserve(dataSize) 相同
  • 我使用 Visual Studio 2017 社区和语言 c++17。统一码。和 MT 构建。我的配置有问题吗?
  • 我在我的编译流中检查它的大小是 typedef long long。但是当我用streamsize创建long long variabel和initiliziation时。示例结果无法转换可能丢失的数据。
  • 我目前的工作代码是我返工 itu 不使用向量,而是使用新的手动动态分配。但我需要自己实现旋转
猜你喜欢
  • 2019-03-12
  • 1970-01-01
  • 2019-10-07
  • 2023-01-07
  • 2020-06-28
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多