Как уже указывал Сет, это проблема с языком и тем, как анализируется выражение. В основном, когда компилятор находит выражение MyClass a(string())
, он интерпретирует его как объявление функции a
, которая имеет сигнатуру MyClass (std::string (*)())
(дополнительная (*)
получается из неявного преобразования функции в указатель на функцию в аргументах).
Существуют различные подходы к преодолению этого синтаксиса в вашем конкретном случае:
MyClass a(""); // 1
MyClass b = std::string(); // 2
MyClass c(( std::string() )); // 3
Первый подход заключается не в использовании выражения T()
для создания значения r, а в константном литерале, который будет выдавать тот же результат. Недостатком этого подхода является то, что в данном конкретном случае вы можете использовать литерал, но это же решение не может быть применено к другим типам (т. Е. Если у вас был свой собственный тип, у которого был только конструктор по умолчанию)
Второй подход позволяет избежать прямой инициализации, поскольку альтернативный синтаксис не может быть проанализирован как объявление функции. Проблема с этим подходом состоит в том, что, хотя результат в вашем конкретном случае одинаков, он требует, чтобы конструктор не был явным . (То есть, если ваш конструктор был объявлен explicit MyClass( std::string const & )
, он потерпит неудачу, но это не будет
Третий подход заключается в добавлении дополнительного набора скобок вокруг первого аргумента в конструктор (обратите внимание, что та же проблема при синтаксическом анализе произошла бы с MyClass a(std::string(), std::string())
). Проблема с этим подходом (мнением) в том, что он уродлив, но в остальном он самый гибкий из всех.