Это известно как «самый неприятный синтаксический анализ» в C ++: то, что для вас выглядит как объявление экземпляра, на самом деле выглядит как объявление функции для компилятора.
std::string name(); //function declaration
std::string name; //object declaration with default constructor
std::stringstream ss(std::string(buf)); //function declaration
std::stringstream ss(std::string buf); //another function declaration
std::stringstream ss(std::string); //also a function declaration
std::stringstream ss(std::string()); //ditto, argument names are optional
std::stringstream ss((std::string(buf))); //object declaration
Обратите внимание на дополнительные скобки в последнем примере. Эти скобки не будут допустимы в объявлении функции.
Первый пример с конструктором по умолчанию хорошо известен. Во втором случае неясность добавляет, что скобки вокруг имен параметров в C ++ являются допустимыми, но необязательными. Например, вы можете определить функцию следующим образом:
void foo(int (bar))
{}
По сути, вы сталкиваетесь с этим каждый раз, когда все аргументы конструктора являются временными значениями от вызовов конструктора, которые принимают 0 или 1 аргумент, и быстрое решение состоит в том, чтобы заключить в один из аргументов дополнительные скобки.