Вопрос

После тщательного прочтения ISO/IEC 14882, Язык программирования – C++ Я все еще не уверен, почему const необходим для неявного преобразования в пользовательский тип с помощью конструктора с одним аргументом, подобного следующему

#include <iostream>

class X {
public:
   X( int value ) {
      printf("constructor initialized with %i",value);
   }
}

void implicit_conversion_func( const X& value ) {
   //produces "constructor initialized with 99"
}

int main (int argc, char * const argv[]) {
   implicit_conversion_func(99);
}



Начиная с раздела 4, строка 3

Выражение e может быть неявно преобразовано в тип T тогда и только тогда, когда объявление T t=e;является хорошо сформированной для некоторой изобретенной временной переменной t (8.5).Некоторые языковые конструкции требуют, чтобы выражение было преобразовано в логическое значение.Говорят, что выражение e, появляющееся в таком контексте, контекстуально преобразовано в bool и является корректно сформированным тогда и только тогда, когда объявление bool t(e);является хорошо сформированной для некоторой изобретенной временной переменной t (8.5).Эффект любого неявного преобразования такой же, как при выполнении объявления и инициализации, а затем использовании временной переменной в качестве результата преобразования.Результатом является значение lvalue, если T является ссылочным типом lvalue (8.3.2), и значение rvalue в противном случае.Выражение e используется в качестве lvalue тогда и только тогда, когда инициализация использует его в качестве lvalue.

После этого я нашел раздел об инициализаторах, связанных с пользовательскими типами, в строке 6 8.5

Если программа вызывает инициализацию по умолчанию объекта с постоянным типом T, T должен быть типом класса с предоставленным пользователем конструктором по умолчанию.

Наконец, я дошел до 12.3, строка 2 о пользовательских преобразованиях, в которой говорится

Пользовательские преобразования применяются только там, где они однозначны (10.2, 12.3.2).

Излишне говорить, что 10.2 и 12.3.2 не ответили на мой вопрос.

  1. Может ли кто-нибудь пролить некоторый свет на то, какой эффект const влияет на неявные преобразования?
  2. Означает ли использование const сделать преобразование "однозначным" для строки 12.3 2?
  3. Делает const как-то повлиять на значение по сравнениюзначение, о котором говорилось в разделе 4?
Это было полезно?

Решение

На самом деле это не имеет большого отношения к тому, что преобразование является неявный.Более того, на самом деле это не имеет особого отношения к преобразования.Речь действительно идет о значения rv против. значения.

Когда вы конвертируете 99 чтобы ввести X, в результате получается значение rv.В C ++ результаты преобразований всегда являются rvalues (если только вы не преобразуете в ссылочный тип).В C ++ запрещено присоединять неконстантные ссылки к rvalues.

Например, этот код не будет компилироваться

X& r = X(99); // ERROR

потому что он пытается прикрепить неконстантную ссылку к rvalue.С другой стороны, этот код в порядке

const X& cr = X(99); // OK

потому что совершенно нормально присоединять ссылку const к rvalue.

То же самое происходит и в вашем коде.Тот факт, что это включает в себя неявное преобразование, как бы не относится к делу.Вы можете заменить неявное преобразование с явным один

implicit_conversion_func(X(99));

и в итоге оказываемся в той же ситуации:с const он компилируется, без const это не так.

Опять же, единственная роль, которую играет преобразование (явное или неявное) здесь, заключается в том, что оно помогает нам получить rvalue .В общем, вы можете создать rvalue каким-либо другим способом и столкнуться с той же проблемой

int &ir = 3 + 2; // ERROR
const int &cir = 3 + 2; // OK

Другие советы

В соответствии с разделом 5.2.2 пункт 5, когда аргумент на функцию имеет const Справочный тип, временная переменная автоматически вводится при необходимости. В вашем примере результат RVALUE X(99) должен быть введен во временную переменную, чтобы эта переменная была передана const ссылка на implicit_conversion_func.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top