Создать std :: string из std :: istreambuf_iterator, странная синтаксическая причуда
2645 просмотра
1 ответ
Я нашел где-то следующую идиому для чтения файла в строку:
std::ifstream file("path/to/some/file.ext");
std::string contents(
std::istreambuf_iterator<char>(file),
(std::istreambuf_iterator<char>())
);
Который работает просто отлично, как есть. Однако, если я уберу скобки вокруг второго аргумента итератора, то есть:
std::string contents(
std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>()
);
Как только я пытаюсь вызвать любой метод для строкового объекта, например:
const char *buffer = contents.c_str();
Я получаю ошибку компиляции формы:
error: request for member 'c_str' in 'contents', which is of non-class type 'std::string(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)()) {aka std::basic_string<char>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)())}'
Также, если я попытаюсь присвоить эту строку другой:
std::string contents2 = contents;
Я получаю ошибку в форме:
error: conversion from 'std::string(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)()) {aka std::basic_string<char>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)())}' to non-scalar type 'std::string {aka std::basic_string<char>}' requested
Почему это? Я не вижу причин, по которым эти круглые скобки нужны, тем более они влияют на определение типа contents
переменной. Я использую g ++ 4.8.2.
Ответы (1)
17 плюса
Вот пример Most Vexing Parse :
std::string contents(
std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>()
);
Оператор анализируется как объявление именованной функции, contents
которая принимает два параметра. Один параметр - это переменная с именем file
типа std::istreambuf_iterator
, а второй - функция, которая не принимает аргументов и возвращает std::istreambuf_iterator
. Указание имен параметров функции не является обязательным.
Обтекание хотя бы одного из выражений в скобках приводит к тому, что оно анализируется как определение переменной.
C ++ 11 решает эту проблему с помощью равномерной инициализации :
std::string contents{std::istreambuf_iterator<char>{file}, {}};
Автор: 0x499602D2
Размещён: 27.08.2014 01:13
Вопросы из категории :
- c++ What are the barriers to understanding pointers and what can be done to overcome them?
- c++ Какой самый простой способ для анализа файла INI в C ++?
- c++ Когда вы должны использовать «друг» в C ++?
- c++ Как вы очищаете переменную stringstream?
- c++ В C ++ конструктор и деструктор могут быть встроенными функциями?
- c++ Что такое виртуальный базовый класс в C ++?
- c++ В чем разница между #include <filename> и #include "filename"?
- c++ Какой самый лучший бесплатный детектор утечки памяти для программы на C / C ++ и ее подключаемых библиотек DLL?
- c++ Как преобразовать std :: string в LPCWSTR в C ++ (Unicode)
- c++ Regular cast vs. static_cast vs. dynamic_cast
- stl Зачем использовать итераторы вместо индексов массива?
- stl Инициализация статического std :: map <int, int> в C ++
- stl К STL или! STL, вот в чем вопрос
- stl Строка c_str () против данных ()
- stl Объединение двух стандартных: векторов
- stl Является ли list :: size () действительно O (n)?
- stl Как отсортировать std :: vector по значениям другого std :: vector?
- stl Проверка контейнеров STL в Xcode
- stl Как вы вставляете с reverse_iterator
- stl Форвард объявить контейнер STL?