Почему неявное преобразование не разрешено в форме копирования инициализации, если я не указываю явное? [дубликат]C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Почему неявное преобразование не разрешено в форме копирования инициализации, если я не указываю явное? [дубликат]

Сообщение Anonymous »

Я знаю, что в C++ мы не можем использовать явный конструктор с копирующей формой инициализации (с =), когда происходит неявное преобразование. Другими словами, мы можем использовать копию формы инициализации, если явный не указан, когда происходит неявное преобразование.
Итак, в следующем фрагменте кода:

Код: Выделить всё

#include 

class A {
public:
A(const std::string& s = std::string()) :
ps(new std::string(s)) { }

A(const A& p) :
ps(new std::string(*p.ps)), i(p.i) { }
A& operator=(const A&);
~A() { delete ps; }
private:
std::string* ps;
int i;
};

A& A::operator=(const A& rhs) {
auto newp = new std::string(*rhs.ps);
delete ps;
ps = newp;
i = rhs.i;
return *this;
}

int main() {
A v = "abc";
}
Я ожидаю, что "abc" можно будет неявно преобразовать в const std::string и, следовательно, в первый конструктор A(const std::string& s) будет вызван. Поскольку я не указал явный для этого конструктора, я не вижу ничего, что могло бы этому помешать. Но я получаю сообщение об ошибке:

невозможно преобразовать константу char [4] в A

В книге «C++ Primer» я прочитал «Явные конструкторы могут использоваться только для прямой инициализации» в разделе 7.5.4 «Неявные преобразования типов классов». Я думаю, насколько я понимаю, такое неявное преобразование в форме инициализации копии не допускается только тогда, когда конструктор является явным.
Но я этого не указывал, и там задействовано только одно преобразование. Итак, я думаю, что A v = "abc"; должно было сработать. Я не понимаю, почему это невозможно.
========================== ======================
Людям, которые закрыли мой вопрос:
Я не спрашиваю «Сколько неявных преобразований» допустимый. Я четко знаю, что допускается не более одного неявного преобразования. Суть моего вопроса в том, что считается неявным преобразованием. Например, почему компилятор не вызывает строку Ctor для создания переменной, когда у нас уже есть строка, полученная в результате одного неявного преобразования? Почему компилятор выполняет дальнейшее неявное преобразование для вызова копии Ctor? Какие изменения мы можем внести в фрагмент кода, чтобы сделать эти правила более понятными, скажем, добавив явный к одному или двум Ctor? Пожалуйста, не спешите закрывать вопрос, если вы не уловили основную мысль и тонкость вопроса. Это только вредит этому сайту.
Если люди, закрывшие мой вопрос, не убеждены. НатанОливер считает, что копирующая форма инициализации (с =) должна использовать копию Ctor. Вскоре JaMiT предлагает эксперимент: A v = std::string{"abc"};. Это работает, но не использует копию Ctor, хотя использует форму инициализации копирования (с =). На самом деле он использует первую строку Ctor. Почему?
Теперь мы можем явно добавить к первой строке Ctor, и произойдет ошибка. В тексте «C++ Primer» говорится: «Одним из контекстов, в которых происходят неявные преобразования, является использование копирующей формы инициализации (с =) (раздел 3.2.1, стр. 84). Мы не можем использовать явный конструктор с этой формой инициализация;" В этом предложении ошибка связана с тем, что мы используем = AND и есть неявные преобразования. Но в этом эксперименте неявного преобразования нет. Так почему же эта ошибка?
Теперь вы можете возразить, что это потому, что «мы должны использовать прямую инициализацию», как утверждается в тексте. Но если мы изменим определение переменной v на A v = A(std::string("abc"));, ошибки не будет. Это копия
инициализации (с =), и строка Ctor все еще является явной. Как объяснить?
Так что мой вопрос можно копнуть глубже, чем так называемый дублированный вопрос. Было бы грубо закрывать мой вопрос, и поэтому мы потеряли возможность узнать больше из моего вопроса.

Подробнее здесь: https://stackoverflow.com/questions/785 ... ion-when-i
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»