Почему const для неявного преобразования?
после продолжительного чтения 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.
после этого я нашел раздел об инициализаторах, связанных с пользовательскими типами в строке 8.5 6
если программа вызывает инициализацию по умолчанию объекта типа T, отвечающего требованиям const, T должен быть типом класса с предоставленным пользователем значением по умолчанию конструктор.
наконец, я оказался в 12.3 строке 2 о пользовательских преобразованиях, в которых говорится
пользовательские преобразования применяются только там, где они однозначны (10.2, 12.3.2).
Излишне говорить, 10.2 и 12.3.2 не ответили на мой вопрос.
- может кто-нибудь пролить свет на то, что эффект
const
на неявные преобразования? - использование
const
сделать преобразование "однозначный" в 12.3 строка 2? - тут
const
как-то повлиять на lvalue против rvalue, о котором говорилось в разделе 4?
2 ответов
это на самом деле не имеет большого отношения к преобразованию подразумевается. Более того, это не имеет большого отношения к преобразование. Это действительно о правосторонние значения и значения lvalue.
при конвертации 99
типа X
, в результате правосторонним значением. В C++ результаты преобразований всегда rvalues (если вы не конвертируете в ссылочный тип). В C++ запрещено прикреплять ссылки non-const к значений rvalue.
например, этот код не будет компилироваться
X& r = X(99); // ERROR
потому что он пытается прикрепить ссылку non-const к 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 раздела 5.2.2, когда аргумент функции имеет значение const
тип ссылки, временная переменная автоматически вводится при необходимости. В вашем примере результат rvalue X(99)
должен быть помещен во временную переменную, чтобы эта переменная могла быть передана const
ссылка implicit_conversion_func
.