Почему явный конструктор boost :: shared_array вызывает ошибку? - PullRequest
3 голосов
/ 26 марта 2011
boost::shared_array<char const *> x(new char const *[n]);

В строке выше (n целое число не больше 100) я создаю char const** (const char**) и помещаю его в интеллектуальный указатель x для удаления массивов при x удалено.И для меня ясно, как и почему эта работа.

boost::shared_array<char const *> x = new char const *[n];

Теперь давайте посмотрим на вторую строку.Здесь, на мой взгляд, мы делаем точно так же, как и в первом случае.Да, на первый взгляд может показаться, что здесь мы конструируем x через NULL (значение по умолчанию параметра конструкторов shared_array), затем вызываем operator=, но это ошибка, и, как я знаю, в этом случае вместо operator= будет вызыватьсяconstructor с указателем, созданным new opeartor.

Но, несмотря на это, я получаю error C2440: 'initializing' : cannot convert from 'const char **' to 'boost::shared_array<T>

Единственная проблема, которую я вижу, это явный конструктор boost::shared_array<T>.Но я не знаю, в чем проблема?Почему явный конструктор вызывает эту ошибку?И если проблема не в явном конструкторе, то где, почему?

Ответы [ 3 ]

3 голосов
/ 26 марта 2011

Ваше предположение верно.

Во второй строке вы пытаетесь неявно вызвать конструктор: вы хотите, чтобы компилятор C ++ понял, что конструктор доступенкоторый принимает T* и использует его.Однако, поскольку конструктор помечен как явный , он не может быть вызван таким образом.

См., Например, обсуждение по адресу http://www.go4expert.com/forums/showthread.php?t=20756.

2 голосов
/ 26 марта 2011

Да, «проблема» в том, что конструктор T* для shared_array равен explicit. Это запрещает строить с =.

1 голос
/ 29 июня 2011

Теперь давайте посмотрим на вторую строку. Вот по моему мы делаем точно так же, как в первом случае. Да в На первый взгляд нам может показаться, что здесь мы построение x через NULL (значение по умолчанию конструкторов shared_array параметр) затем вызывая оператор =, но это ошибка, и как я знаю в этом регистр вместо оператора = будет вызываемый конструктор с указателем создан новым оператором.

Это не совсем так. Вот что на самом деле происходит в общем случае. Предположим, у вас есть

struct A
{
   /*explicit*/ A(int){}

};

A a = 7;

На самом деле это не эквивалентно A a(7). При инициализации A a = 7 вы вызываете 2 конструктора, конструктор, который использует int для создания временного, и конструктор копирования для инициализации a. Конечно, в большинстве случаев это избыточно, и компилятору разрешено опускать вызов конструктора копирования (что явно указано в стандарте), но, тем не менее, требует , чтобы он был независимо о том, решит ли он пропустить вызов или нет.

struct A
{
   /*explicit*/ A(int){}
   private: A(A const &){}  
};

A a = 7;

Теперь это будет ошибка во время компиляции. Если вы добавите несколько сообщений трассировки в оба конструктора, вы, скорее всего, увидите, что конструктор копирования в любом случае не вызывается, но это не имеет значения - он должен быть там и доступен.

Относительно того, почему explicit мешает вам вызывать вышеуказанный синтаксис, теперь должно быть ясно - потому что этот конструктор вызывается неявно для инициализации временного, а не a.

HTH и Cheers,:)

...