, Не очень читаемый, хотя ...

отрим этот очень простой код:

#include <memory>

class Foo
{
public:
    Foo() {};
};

class Bar
{
public:
    Bar( const std::shared_ptr<Foo>& foo ) {}
}; 

int main()
{
    Foo* foo = new Foo;
    Bar bar( std::shared_ptr<Foo>( foo ) );
    return 0;
}

Почему отчеты Visual Studio

warning C4930: 'Bar bar(std::shared_ptr<Foo>)': prototyped function not called (was a variable definition intended?)

и нетbar объект создан ... как можно эту строкуBar bar( std::shared_ptr<Foo>( foo ) ); интерпретировать как определение функции?

Я проверилЕсть ли в скобках после имени типа разница с новым? а такжеC ++: предупреждение: C4930: функция-прототип не вызвана (было ли предназначено определение переменной?), но я чувствую, что моя проблема здесь другая, так как я не использовал синтаксисFoo() ниBar().

Изменить: Обратите внимание, что он успешно компилирует:

Foo* foo = new Foo;
std::shared_ptr<Foo> fooPtr( foo );
Bar bar( fooPtr );
 Quentin14 сент. 2017 г., 14:18
@RichardHodges, как и MSVC, это всего лишь предупреждение.眠 り ネ ロ ク правильно.
 Caduchon14 сент. 2017 г., 14:23
Более того, в соответствии с вашей идеей, разделяемый указатель уничтожается на следующей строке, приводя к дислокации ресурса и вызывая сбой вашего объекта (возможно).
 aschepler14 сент. 2017 г., 14:18
@RichardHodges Да, это правильная программа. Который не делает то, что почти наверняка предполагалось (Bar конструктор никогда не будет вызван) из-за самого разборчивого разбора.
 El Profesor14 сент. 2017 г., 14:14
C ++ самый неприятный анализ.
 jpo3814 сент. 2017 г., 14:31
@Caduchon: Это было только для того, чтобы выделить пример в MCVE

Ответы на вопрос(1)

Решение Вопроса

Эта проблема оC ++ самый неприятный анализ, Заявление:

Bar bar( std::shared_ptr<Foo>( foo ) );

объявляет функцию с именемbar это возвращаетBar и принимает аргумент под названиемfoo типаstd::shared_ptr<Foo>.

Внутренние скобки не имеют никакого эффекта. Это как если бы вы написали следующее:

Bar bar( std::shared_ptr<Foo> foo);

Предполагая C ++ 11 (так как вы уже используетеstd::shared_ptr) вы могли бы использоватьсинтаксис скобки вместокруглая скобка:

Bar bar(std::shared_ptr<Foo>{foo});

Это на самом деле построить объектbar типаBar, поскольку вышеприведенное утверждение не может быть интерпретировано как объявление из-за скобок.

 Arne Vogel14 сент. 2017 г., 16:55
Возможное решение C ++ 98 или TR1 - использовать двойные скобки после предполагаемого имени переменной. Как вы указали, имя параметра может быть заключено в произвольные скобки, но не во весь список параметров, даже если он содержит только одно объявление параметра. Так, например:Bar bar((std::tr1::shared_ptr<Foo>(foo))), Не очень читаемый, хотя ...
 jpo3814 сент. 2017 г., 14:18
Вы имеете в виду, что это эквивалентноBar bar( std::shared_ptr<Foo> foo );?
 aschepler14 сент. 2017 г., 14:20
Правильно, но может быть лучшим ответом, если у вас есть объяснение или ссылка о Most Vexing Parse и вы предлагаете решение.

Ваш ответ на вопрос