Согласно стандарту C ++ (8.5.1.3 Явное преобразование типов (функциональная запись))
1 Спецификатор простого типа (10.1.7.2) или спецификатор типа (17.7)
за которым следует необязательный список выражений в скобках или
Braced-init-list (инициализатор) создает значение указанного
введите данный инициализатор ...
Итак, выражение в этом выражении оператора
shared_ptr<int>(p);
выглядит как явное (функциональное) выражение преобразования типа.
С другой стороны, декларатор в объявлении может быть заключен в скобки. Например
int ( x );
является действительным объявлением.
Итак, это утверждение
shared_ptr<int>(p);
можно интерпретировать как объявление типа
shared_ptr<int> ( p );
Итак, есть какая-то неясность.
Стандарт C ++ разрешает эту неоднозначность следующим образом (9.8 Разрешение неоднозначности)
1 В грамматике существует двусмысленность, связанная с выражениями-выражениями
и объявления: оператор выражения с функциональным стилем
явное преобразование типов (8.5.1.3), поскольку его крайнее левое подвыражение может
быть неотличимым от декларации, где первый декларатор
начинается с (. В этих случаях оператором является объявление .
Таким образом, этот оператор во внутреннем кодовом блоке
shared_ptr<int>(p);
- это объявление нового общего указателя с именем p
, которое скрывает предыдущее объявление объекта с тем же именем p
во внешнем кодовом блоке и создается с помощью конструктора defalut
constexpr shared_ptr() noexcept;
Согласно описанию этого конструктора
2 Эффекта: создание пустого объекта shared_ptr.
3 Постусловия: use_count () == 0 && get () == nullptr.
Если вы хотите иметь дело с выражением вместо объявления, тогда все, что вам нужно сделать, это заключить тело выражения в скобки, чтобы получить первичное выражение в выражении выражения.
Вот демонстрационная программа.
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> p( new int( 42 ) );
std::cout << "#1: " << p.use_count() << '\n';
{
std::cout << "#2: " << p.use_count() << '\n';
( std::shared_ptr<int>( p ) );
std::cout << "#3: " << p.use_count() << '\n';
}
std::cout << "#4: " << p.use_count() << '\n';
return 0;
}
В этом случае его вывод равен
#1: 1
#2: 1
#3: 1
#4: 1