ReadFile std :: unique_ptr против std :: vector против std :: string

0

Какое из следующих было бы наиболее эффективным и почему? Я склоняюсь к unique_ptr потому что я думаю, что при возврате прочитанных данных копия не выполняется. Это просто передача права собственности на указатель.

Например, я думаю, что строка-версия создала бы временную строку, считывала бы данные в нее и, вернувшись, скопировала бы ее данные в назначенный результат?

Однако я не уверен, что я прав. Любые идеи, что я имею в виду, и что лучше?

UniquePtr:

std::unique_ptr<const char[]> ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);

    if (file.is_open())
    {
        file.seekg(0, std::ios::end);
        std::size_t size = file.tellg();
        std::unique_ptr<char[]> result(new char[size]);
        file.seekg(0, std::ios::beg);
        file.read(result.get(), size);
        file.close();
        return std::move(result);
    }
    return nullptr;
}

Вектор:

std::string ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);

    if (file.is_open())
    {
        file.seekg(0, std::ios::end);
        std::vector<std::int8_t> buffer(file.tellg());
        file.seekg(0, std::ios::beg);
        file.read(result.data(), result.size());
        file.close();
        return std::string(result.data());
    }
    return std::string();
}

Строка:

std::string ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);

    if (file.is_open())
    {
        std::string result = std::string();
        file.seekg(0, std::ios::end);
        result.resize(file.tellg());
        file.seekg(0, std::ios::beg);
        file.read(&result[0], result.size());
        file.close();
        return result;
    }
    return std::string();
}
  • 3
    Ваш unique_ptr<char> должен быть unique_ptr<char[]> ! В любом случае, возврат по значению перемещается, если NRVO не происходит. Копирование - последнее средство.
  • 0
    Хорошо, спасибо за это. Изменено. О, и является ли std::unique_ptr единственным, который гарантированно будет перемещен?
Показать ещё 4 комментария
Теги:
c++11
stl

2 ответа

1
Лучший ответ
std::string ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);
    std::string result = std::string();

    if (file.is_open())
    {
        file.seekg(0, std::ios::end);
        result.resize(file.tellg());
        file.seekg(0, std::ios::beg);
        file.read(&result[0], result.size());
        file.close();
    }
    return result;
}

У меня нет доказательств, но если функция имеет только один возврат, копирование elision может быть реализовано компилятором, если есть две функции возврата внутри функции, копирование elision может работать не так, как ожидалось ~~~

0

 return std::string(result.data());

будет работать только в том случае, если данные заканчиваются нулями.

Помимо этого усложнения, он ненужно копирует из вектора в строку.

std::string код std::string наиболее естественен для чтения текста (текстовый режим открытия файла).

Вы не увидите большой разницы в производительности, так как файл i/o затмевает остальное, но в любом случае с С++ 03 вы, скорее всего, получите Оптимизацию возвращаемого значения (зависит от компилятора), а с С++ 11 вы получите переместите оптимизацию результата, если вы просто используете std::move.

  • 0
    Я не уверен в этом поиске действий в потоках текстового режима. Я считаю, что это по крайней мере немного подозрительно. Я оставляю это другим, чтобы проверить все же.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню