Ответ 1
Это С++ "самый неприятный синтаксический анализ". Быстрый Google для этого должен показать множество хитов с большим количеством деталей. Основной ответ заключается в том, что да, компилятор рассматривает это как объявление функции, а С++ требует, чтобы он это делал. Нет ничего плохого в вашем компиляторе (по крайней мере в этом отношении).
Если вам будет удобно, у вас будет много хорошей компании, столкнувшись с этим. На самом деле, достаточно распространено то, что С++ 0x добавлен новый синтаксис синтаксиса brace-initializer, во многом потому, что он избегает этой двусмысленности. Используя его, вы можете написать что-то вроде:
std::string s{std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>()};
Это даст понять, что содержимое фигурных скобок предназначено для значений инициализации s
, а не типов параметров для функции с именем s
. Я не знаю, есть ли у Apple порт, но gcc принимает новый синтаксис версии 4.5 (или так).
Изменить: Перечитывая N3092, Йоханнес (как обычно) вполне корректен. Применяемый язык (§8.5.4/3/5): "Если T имеет конструктор списка инициализаторов, список аргументов состоит из списка инициализаторов как один аргумент, в противном случае список аргументов состоит из элементов инициализатора список".
Итак, поскольку std::string
имеет конструктор-инициализатор-список, это попытается "заполнить" два istreambuf_iterator
в списке инициализаторов и передать это в std::string
ctor, который принимает список инициализаторов, но это будет несоответствие типа, поэтому код не может скомпилироваться. Для другого типа типа, в котором (в отличие от std::string
не было списка инициализаторов ctor), преобразование выше работало бы (спасибо "в противном случае..." в приведенной выше цитате). В случае std::string
вам придется использовать одну из существующих альтернатив, например std::string s = std:string(...)
.
Я извиняюсь за неправильное предложенное исправление - в этом случае, все хуже, потому что он смущает проблему, которая, вероятно, будет чрезмерно запутанной сама по себе, и если что-то потребует тщательного разъяснения, особенно в течение следующих нескольких лет.