Что означает явное ключевое слово?

Что означает ключевое слово explicit в C++?

Я просто хочу указать на то, что со времен C++ 11 explicit может применяться не только к конструкторам. Теперь он применим и к операторам преобразования. Допустим, у вас есть класс BigInt с оператором преобразования в int и явным оператором преобразования в std::string по какой-либо причине. Вы сможете сказать int i = myBigInt;, но вам нужно будет явно выполнить приведение (предпочтительно, используя static_cast), чтобы сказать std::string s = myBigInt;.

chris 30.08.2012 20:52

Не может явным образом также относиться к присваиванию? (например, int x(5);)

Eitan Myron 27.02.2014 09:10

@chris Идея явного неявного преобразования абсурдна. Держитесь подальше от этого!

curiousguy 19.06.2018 23:25

@curiousguy, Явного неявного преобразования нет.

chris 20.06.2018 17:58

@chris Существует явное ключевое слово, которое можно использовать при объявлении неявного преобразования.

curiousguy 20.06.2018 18:52

@curiousguy, это по своей сути неявное преобразование. Размещение explicit декларирует явное преобразование в тип. Никакой скрытности в процессе.

chris 20.06.2018 18:57

@chris Явное преобразование - это плохо определенная концепция.

curiousguy 20.06.2018 19:02

@curiousguy: Что ты имеешь в виду? Все преобразования должны быть неявными? Выпустить всевозможные молчаливые забавные ошибки из-за случайных двусмысленностей? (См., Например, раздел «Проблема безопасного bool» в этот C++ исх. страница или open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2333.html для (гораздо) более подробной информации о том, почему «Явное преобразование - плохо определенная концепция». Это непродуманное утверждение.)

Sz. 03.08.2019 00:53

@Sz. Я имею в виду, что явное преобразование - это не вещь; это мусор. Также «safe bool» - смехотворное «доказательство» полезности идеи «явного оператора», поскольку это даже не приложение этой идеи, а другой набор правил, что означает Единственное практическое использование «явного оператора» в SL является специальным и не применимо к UDT.

curiousguy 03.08.2019 06:24

@ Крис, ты имел в виду это: std::string s = static_cast<std::string>(myBigInt)? Если возможно, не могли бы вы подробнее рассказать о своем первом комментарии? Заранее большое спасибо!

Milan 26.01.2021 04:42

@Milan, да именно так. Если вам нужна дополнительная информация, этот ответ записывает ее более формально. Обратите внимание, что bool особенный в этом отношении. Эти ответы и поиск «явных операторов преобразования» приведут вас к большему количеству рецензий об этой функции и будут лучше подходить, чем цепочка комментариев.

chris 26.01.2021 04:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3 127
11
931 938
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

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

Вот пример класса с конструктором, который можно использовать для неявных преобразований:

class Foo
{
public:
  // single parameter constructor, can be used as an implicit conversion
  Foo (int foo) : m_foo (foo) 
  {
  }

  int GetFoo () { return m_foo; }

private:
  int m_foo;
};

Вот простая функция, которая принимает объект Foo:

void DoBar (Foo foo)
{
  int i = foo.GetFoo ();
}

и здесь вызывается функция DoBar:

int main ()
{
  DoBar (42);
}

Аргументом является не объект Foo, а int. Однако существует конструктор для Foo, который принимает int, поэтому этот конструктор можно использовать для преобразования параметра в правильный тип.

Компилятору разрешено сделать это один раз для каждого параметра.

Добавление перед конструктором ключевого слова explicit не позволяет компилятору использовать этот конструктор для неявных преобразований. Добавление его в вышеуказанный класс вызовет ошибку компилятора при вызове функции DoBar (42). Теперь необходимо явно вызвать преобразование с помощью DoBar (Foo (42)).

Причина, по которой вы можете захотеть это сделать, - избежать случайной конструкции, которая может скрыть ошибки. Надуманный пример:

  • У вас есть класс MyString(int size) с конструктором, который создает строку заданного размера. У вас есть функция print(const MyString&), и вы вызываете print(3) (когда вы фактически намеревались вызвать print("3")). Вы ожидаете, что он напечатает «3», но вместо этого он напечатает пустую строку длиной 3.

Хорошая запись, вы можете упомянуть акторы с несколькими аргументами с параметрами по умолчанию, которые также могут действовать как один аргумент ctor, например, Object (const char * name = NULL, into type = 0).

maccullt 24.09.2008 05:23

Я думаю, также следует упомянуть, что следует подумать о том, чтобы сделать конструкторы с одним аргументом явными изначально (более или менее автоматически) и удалить явное ключевое слово только тогда, когда требуется неявное преобразование по дизайну. Я думаю, что конструкторы по умолчанию должны быть явными с ключевым словом implicit, чтобы они могли работать как неявные преобразования. Но это не так.

Michael Burr 26.08.2009 21:47

@thecoshman: Вы не объявляете параметрexplicit - вы объявляете конструкторexplicit. Но да: ваши параметры типа Foo должны быть сконструированы explicitely, они не будут сконструированы молча, просто подключив параметры их конструктора в функцию.

Christian Severin 17.06.2011 16:12

Просто к сведению, что при вызове «print (3)» в вашем примере функция должна быть «print (const MyString &»). Здесь "const" является обязательным, потому что 3 преобразуется во временный объект "MyString", и вы не можете привязать временный объект к ссылке, если он не "const" (еще один в длинном списке ошибок C++)

Larry 10.07.2012 16:52

Для полноты картины я добавляю, что в дополнение к преобразованию параметров ключевое слово явный здесь также предотвратит использование формы присваивания копии ctor (например, Foo myFoo = 42;) и потребует явных форм Foo myFoo = Foo (42) ; или Foo myFoo (42);

Arbalest 15.12.2012 04:53

Допустим, у вас есть класс String:

class String {
public:
    String(int n); // allocate n bytes to the String object
    String(const char *p); // initializes object with char *p
};

Теперь, если вы попробуете:

String mystring = 'x';

Символ 'x' будет неявно преобразован в int, а затем будет вызван конструктор String(int). Но это не то, что мог предполагать пользователь. Итак, чтобы предотвратить такие условия, мы определим конструктор как explicit:

class String {
public:
    explicit String (int n); //allocate n bytes
    String(const char *p); // initialize sobject with string p
};

И стоит отметить, что новые обобщенные правила инициализации C++ 0x сделают String s = {0}; некорректным, вместо того, чтобы пытаться вызвать другой конструктор с нулевым указателем, как это сделал бы String s = 0;.

Johannes Schaub - litb 13.12.2010 11:59

Несмотря на то, что это старый вопрос, кажется, стоит указать на несколько моментов (или попросить кого-нибудь меня поправить). Сделав форму int или оба ctors "явными", вы все равно будете иметь ту же ошибку, если бы вы использовали String mystring('x'), имея в виду String mystring("x"), не так ли? Кроме того, из комментария выше я вижу улучшенное поведение String s = {0} по сравнению с String s = 0 благодаря тому, что форма int для ctor стала «явной». Но, помимо знания приоритета ctors, как узнать намерение (то есть, как обнаружить ошибку) этого String s{0}?

Arbalest 05.08.2013 09:23

Почему String mystring = 'x'; преобразуется в int?

InQusitive 22.03.2015 22:51

@InQusitive: 'x' обрабатывается как целое число, потому что Тип данных char - это просто 1-байтовое целое число.

DavidRR 30.04.2015 16:55

Проблема с вашим примером заключается в том, что он работает только с копировать инициализацию (с использованием =), но не с прямая инициализация (без использования =): компилятор по-прежнему будет вызывать конструктор String(int) без генерации ошибки, если вы напишете String mystring('x');, как указал @Arbalest. Ключевое слово explicit предназначено для предотвращения неявных преобразований, которые происходят при прямой инициализации и разрешении функций. Лучшим решением для вашего примера была бы простая перегрузка конструктора: String(char c);.

Maggyero 11.08.2015 23:24

В C++ конструктор только с одним обязательным параметром считается функцией неявного преобразования. Он преобразует тип параметра в тип класса. Хорошо это или нет, зависит от семантики конструктора.

Например, если у вас есть строковый класс с конструктором String(const char* s), вероятно, это именно то, что вам нужно. Вы можете передать const char* функции, ожидающей String, и компилятор автоматически создаст для вас временный объект String.

С другой стороны, если у вас есть класс буфера, конструктор которого Buffer(int size) принимает размер буфера в байтах, вы, вероятно, не хотите, чтобы компилятор незаметно превращал int в Buffer. Чтобы предотвратить это, вы объявляете конструктор с ключевым словом explicit:

class Buffer { explicit Buffer(int size); ... }

Туда,

void useBuffer(Buffer& buf);
useBuffer(4);

становится ошибкой времени компиляции. Если вы хотите передать временный объект Buffer, вы должны сделать это явно:

useBuffer(Buffer(4));

Таким образом, если ваш однопараметрический конструктор преобразует параметр в объект вашего класса, вы, вероятно, не захотите использовать ключевое слово explicit. Но если у вас есть конструктор, который просто принимает один параметр, вы должны объявить его как explicit, чтобы компилятор не удивлял вас неожиданными преобразованиями.

useBuffer ожидает lvalue для своего аргумента, useBuffer(Buffer(4)) не будет работать из-за этого. Поменяв его на const Buffer&, Buffer&& или просто Buffer, он заработает.

pqnet 26.06.2017 16:18

Всегда рекомендуется создавать конструкторы с одним аргументом (включая те, которые имеют значения по умолчанию для arg2, arg3, ...), как уже было сказано. Как всегда с C++: если нет - вы пожалеете ...

Еще одна хорошая практика для классов - сделать создание копий и присваивание частными (или отключить их), если вам действительно не нужно это реализовывать. Это позволяет избежать возможных копий указателей при использовании методов, которые C++ создаст для вас по умолчанию. Другой способ сделать это - унаследовать от boost::noncopyable.

Этот пост написан в 2009 году. Сегодня вы не объявляете их частными, а говорите = delete.

v010dya 02.10.2015 10:08

Ключевое слово explicit превращает конструктор преобразования в конструктор без преобразования. В результате код менее подвержен ошибкам.

прямой ответ, если вы знаете С ++, если нет, вы можете перейти к ответу cjm ...

n611x007 25.01.2017 03:15

Ключевое слово explicit может использоваться для принудительного вызова конструктора явно.

class C{
public:
    explicit C(void) = default;
};

int main(void){
    C c();
    return 0;
}

ключевое слово explicit перед конструктором C(void) сообщает компилятору, что разрешен только явный вызов этого конструктора.

Ключевое слово explicit также может использоваться в операторах приведения типов, определяемых пользователем:

class C{
public:
    explicit inline operator bool(void) const{
        return true;
    }
};

int main(void){
    C c;
    bool b = static_cast<bool>(c);
    return 0;
}

Здесь ключевое слово explicit обеспечивает действительность только явных приведений, поэтому в этом случае bool b = c; будет недопустимым. В подобных ситуациях ключевое слово explicit может помочь программисту избежать неявного, непреднамеренного приведения типов. Это использование стандартизировано в C++ 11.

C c(); в первом примере означает не то, что вы думаете: это объявление функции с именем c, которая не принимает параметров и возвращает экземпляр C.

6502 20.02.2014 01:25

explicit operator bool() также является версией безопасного bool для C++ 11 и может использоваться неявно при проверках условий (и Только при проверках условий, насколько мне известно). Во втором примере эта строка также действительна в main(): if (c) { std::cout << "'c' is valid." << std:: endl; }. Однако, помимо этого, его нельзя использовать без явного приведения типов.

Justin Time - Reinstate Monica 10.02.2016 21:35

"конструктор, который будет вызываться явно" нет

curiousguy 13.06.2018 03:20

@JustinTime Это глупая, сломанная версия безопасного bool. Сама идея явного неявного преобразования абсурдна.

curiousguy 13.06.2018 03:21

@curiousguy Верно. Это немного похоже на кладж, направленный больше на то, чтобы его легко запомнить (вероятно, в надежде на то, что это будет часто использоваться), чем на следование английской логике, и спроектированный так, чтобы не быть полностью несовместимым с предыдущими безопасными реализациями bool (так что вы меньше может что-то сломать, если вы его замените). ИМО, по крайней мере.

Justin Time - Reinstate Monica 19.06.2018 10:14

Этот ответ касается создания объекта с / без явного конструктора, поскольку он не рассматривается в других ответах.

Рассмотрим следующий класс без явного конструктора:

class Foo
{
public:
    Foo(int x) : m_x(x)
    {
    }

private:
    int m_x;
};

Объекты класса Foo можно создавать двумя способами:

Foo bar1(10);

Foo bar2 = 20;

В зависимости от реализации второй способ создания экземпляра класса Foo может сбивать с толку, или не то, что задумал программист. Приставка ключевого слова explicit к конструктору вызовет ошибку компилятора на Foo bar2 = 20;.

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

Также обратите внимание, что конструкторы с

  • аргументы по умолчанию для всех параметров или
  • аргументы по умолчанию для второго параметра и далее

оба могут использоваться как конструкторы с одним аргументом. Так что вы можете сделать их также explicit.

Примером, когда вы намеренно нет хотите сделать конструктор с одним аргументом явным, является создание функтора (посмотрите на структуру add_x, объявленную в ответе это). В таком случае, вероятно, имеет смысл создать объект add_x add30 = 30;.

Здесь - хорошая статья о явных конструкторах.

Конструкторы добавляют неявное преобразование. Чтобы подавить это неявное преобразование, необходимо объявить конструктор с явным параметром.

В C++ 11 вы также можете указать «тип оператора ()» с таким ключевым словом http://en.cppreference.com/w/cpp/language/explicit. С такой спецификацией вы можете использовать оператор в терминах явных преобразований и прямой инициализации объекта.

P.S. При использовании преобразований, определенных ПОЛЬЗОВАТЕЛЕМ (через конструкторы и оператор преобразования типов), разрешается использовать только один уровень неявных преобразований. Но вы можете комбинировать эти преобразования с преобразованиями других языков.

  • вверх по целому ряду (от char до int, float до удвоения);
  • стандартные преобразования (int в double);
  • преобразовать указатели объектов в базовый класс и в void *;

Ключевое слово explicit сопровождает либо

  • конструктор класса X, который нельзя использовать для неявного преобразования первого (любого единственного) параметра в тип X

C++ [class.conv.ctor]

1) A constructor declared without the function-specifier explicit specifies a conversion from the types of its parameters to the type of its class. Such a constructor is called a converting constructor.

2) An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used. A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or valueinitialization (8.5).

  • или функция преобразования, которая рассматривается только для прямой инициализации и явного преобразования.

C++ [class.conv.fct]

2) A conversion function may be explicit (7.1.2), in which case it is only considered as a user-defined conversion for direct-initialization (8.5). Otherwise, user-defined conversions are not restricted to use in assignments and initializations.

Обзор

Явные функции преобразования и конструкторы могут использоваться только для явных преобразований (прямая инициализация или явная операция приведения), в то время как неявные конструкторы и функции преобразования могут использоваться как для неявных, так и для явных преобразований.

/*
                                 explicit conversion          implicit conversion

 explicit constructor                    yes                          no

 constructor                             yes                          yes

 explicit conversion function            yes                          no

 conversion function                     yes                          yes

*/

Пример использования структур X, Y, Z и функций foo, bar, baz:

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

struct Z { };

struct X { 
  explicit X(int a); // X can be constructed from int explicitly
  explicit operator Z (); // X can be converted to Z explicitly
};

struct Y{
  Y(int a); // int can be implicitly converted to Y
  operator Z (); // Y can be implicitly converted to Z
};

void foo(X x) { }
void bar(Y y) { }
void baz(Z z) { }

Примеры относительно конструктора:

Преобразование аргумента функции:

foo(2);                     // error: no implicit conversion int to X possible
foo(X(2));                  // OK: direct initialization: explicit conversion
foo(static_cast<X>(2));     // OK: explicit conversion

bar(2);                     // OK: implicit conversion via Y(int) 
bar(Y(2));                  // OK: direct initialization
bar(static_cast<Y>(2));     // OK: explicit conversion

Инициализация объекта:

X x2 = 2;                   // error: no implicit conversion int to X possible
X x3(2);                    // OK: direct initialization
X x4 = X(2);                // OK: direct initialization
X x5 = static_cast<X>(2);   // OK: explicit conversion 

Y y2 = 2;                   // OK: implicit conversion via Y(int)
Y y3(2);                    // OK: direct initialization
Y y4 = Y(2);                // OK: direct initialization
Y y5 = static_cast<Y>(2);   // OK: explicit conversion

Примеры функций преобразования:

X x1{ 0 };
Y y1{ 0 };

Преобразование аргумента функции:

baz(x1);                    // error: X not implicitly convertible to Z
baz(Z(x1));                 // OK: explicit initialization
baz(static_cast<Z>(x1));    // OK: explicit conversion

baz(y1);                    // OK: implicit conversion via Y::operator Z()
baz(Z(y1));                 // OK: direct initialization
baz(static_cast<Z>(y1));    // OK: explicit conversion

Инициализация объекта:

Z z1 = x1;                  // error: X not implicitly convertible to Z
Z z2(x1);                   // OK: explicit initialization
Z z3 = Z(x1);               // OK: explicit initialization
Z z4 = static_cast<Z>(x1);  // OK: explicit conversion

Z z1 = y1;                  // OK: implicit conversion via Y::operator Z()
Z z2(y1);                   // OK: direct initialization
Z z3 = Z(y1);               // OK: direct initialization
Z z4 = static_cast<Z>(y1);  // OK: explicit conversion

Зачем использовать функции преобразования или конструкторы explicit?

Конструкторы преобразования и неявные функции преобразования могут вносить неоднозначность.

Рассмотрим структуру V, конвертируемую в int, структуру U, неявно конструируемую из V, и функцию f, перегруженную для U и bool соответственно.

struct V {
  operator bool() const { return true; }
};

struct U { U(V) { } };

void f(U) { }
void f(bool) {  }

Вызов f неоднозначен при передаче объекта типа V.

V x;
f(x);  // error: call of overloaded 'f(V&)' is ambiguous

Компилятор не знает, использовать ли конструктор U или функцию преобразования для преобразования объекта V в тип для перехода к f.

Если конструктором U или функцией преобразования V будет explicit, двусмысленности не возникнет, поскольку будет рассматриваться только неявное преобразование. Если оба явны, вызов f с использованием объекта типа V должен быть выполнен с использованием явного преобразования или операции приведения.

Конструкторы преобразования и неявные функции преобразования могут привести к неожиданному поведению.

Рассмотрим функцию, печатающую некоторый вектор:

void print_intvector(std::vector<int> const &v) { for (int x : v) std::cout << x << '\n'; }

Если бы размер-конструктор вектора не был бы явным, можно было бы вызвать функцию следующим образом:

print_intvector(3);

Чего можно было ожидать от такого звонка? Одна строка, содержащая 3, или три строки, содержащие 0? (Где второй - то, что происходит.)

Использование ключевого слова explicit в интерфейсе класса заставляет пользователя интерфейса явно указывать желаемое преобразование.

Как выразился Бьярн Страуструп (в "The C++ Programming Language", 4th Ed., 35.2.1, pp. 1011) на вопрос, почему std::duration не может быть неявно сконструирован из простого числа:

If you know what you mean, be explicit about it.

Ссылка Cpp всегда полезна !!! Подробности о явном спецификаторе можно найти в здесь. Возможно, вам также понадобится посмотреть на неявные преобразования и копирование-инициализация.

Быстрый взгляд

The explicit specifier specifies that a constructor or conversion function (since C++11) doesn't allow implicit conversions or copy-initialization.

Пример следующим образом:

struct A
{
    A(int) { }      // converting constructor
    A(int, int) { } // converting constructor (C++11)
    operator bool() const { return true; }
};

struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator bool() const { return true; }
};

int main()
{
    A a1 = 1;      // OK: copy-initialization selects A::A(int)
    A a2(2);       // OK: direct-initialization selects A::A(int)
    A a3 {4, 5};   // OK: direct-list-initialization selects A::A(int, int)
    A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
    A a5 = (A)1;   // OK: explicit cast performs static_cast
    if (a1) cout << "true" << endl; // OK: A::operator bool()
    bool na1 = a1; // OK: copy-initialization selects A::operator bool()
    bool na2 = static_cast<bool>(a1); // OK: static_cast performs direct-initialization

//  B b1 = 1;      // error: copy-initialization does not consider B::B(int)
    B b2(2);       // OK: direct-initialization selects B::B(int)
    B b3 {4, 5};   // OK: direct-list-initialization selects B::B(int, int)
//  B b4 = {4, 5}; // error: copy-list-initialization does not consider B::B(int,int)
    B b5 = (B)1;   // OK: explicit cast performs static_cast
    if (b5) cout << "true" << endl; // OK: B::operator bool()
//  bool nb1 = b2; // error: copy-initialization does not consider B::operator bool()
    bool nb2 = static_cast<bool>(b2); // OK: static_cast performs direct-initialization
}

Да! Я думаю, что изучение примера и описания ключевого слова в cppreference - лучший способ понять explicit.

dekuShrub 18.04.2018 13:21

explicit operator bool() против if - особый случай. Невозможно воспроизвести его с помощью определенных пользователем Bool, explicit operator Bool() и функции If.

curiousguy 13.06.2018 03:07

Конструкторы явного преобразования (только C++)

The explicit function specifier controls unwanted implicit type conversions. It can only be used in declarations of constructors within a class declaration. For example, except for the default constructor, the constructors in the following class are conversion constructors.

class A
{
public:
    A();
    A(int);
    A(const char*, int = 0);
};

Следующие заявления являются законными:

A c = 1;
A d = "Venditti";

Первое объявление эквивалентно A c = A( 1 );.

Если вы объявите конструктор класса как explicit, предыдущие объявления будут недопустимыми.

Например, если вы объявите класс как:

class A
{
public:
    explicit A();
    explicit A(int);
    explicit A(const char*, int = 0);
};

Вы можете присваивать только значения, которые соответствуют значениям типа класса.

Например, допустимы следующие утверждения:

  A a1;
  A a2 = A(1);
  A a3(1);
  A a4 = A("Venditti");
  A* p = new A(1);
  A a5 = (A)1;
  A a6 = static_cast<A>(1);

"присвоить значения" Мы не обсуждаем здесь оператор присваивания.

curiousguy 26.01.2019 03:17

Это прямая копия с ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/rzarg/…

Henry 19.09.2019 23:47

Копирование и вставка ответа из авторитетного источника без каких-либо ссылок по-прежнему приносит этому парню колоссальные 55 баллов. Неплохо для «старания».

rags2riches 18.06.2020 13:01

reputable source и прямая копия вводят понятие explicit A(), хотя это просто шум (компилятор должен его игнорировать), но не должен присутствовать в ответе с 55 баллами.

malat 26.06.2020 10:49

авторитетный источник ошибается, когда говорит: «Он [явный] может использоваться только в объявлениях конструкторов ...», поскольку он также может использоваться в объявлении функций преобразования.

Don Slowik 09.01.2021 00:42

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