C ++ всегда использует явный конструктор

Прочитав следующий блог:

http://xania.org/200711/ambiguous-overloading

Я начал задавать себе вопрос: «Разве я не всегда должен четко определять свои конструкторы?»

Итак, я начал читать больше, чем узнал эту статью:

http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/

Который показывает другой пример, а также объясняет его мысли за этим.
Но, конечно, это мысли одного блоггера.

Я был бы рад услышать от некоторых из вас, что было бы неплохо, что вы думаете о манере, каков ваш опыт с предметом и несколько примеров в любом случае.

29

Решение

Традиционная мудрость заключается в том, что конструкторы принимая один параметр (явно или эффективно с помощью параметров по умолчанию) должны быть отмечены explicit, если они не определяют преобразование (std::string быть конвертируемым из const char* являясь одним из примеров последнего). Вы сами выяснили причины, по которым неявные преобразования действительно могут сделать жизнь сложнее, чем она должна быть.

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

Хотя может показаться, что маркировка всех других видов конструкторов explicit не больно, я бы с этим поспорил. Потому что пока explicit не влияет на конструктор, принимающий несколько аргументов в C ++ 03, он имеет влияние в C ++ 11. Чтобы поместить это в код:

struct foo {
explicit foo(int i);
foo(int i, int j);
explicit foo(int i, int j, int k);
};

foo make_foo()
{
/* Not C++11-specific: */
// Error: no conversion from int to foo
return 42;

// Okay: construction, not conversion
return foo(42);

// Okay: constructions
return foo(42, 42);
return foo(42, 42, 42);

/* C++11 specific: */
// Error: no conversion from int to foo
return { 42 };

// Not an error, not a conversion
return { 42, 42 };

// Error! Constructor is explicit
return { 42, 42, 42 };
// Not an error, direct-initialization syntax
return foo { 42, 42, 42 };
}

Я лично нахожу это ненужным многословным в функции, которая возвращает foo Я должен явно вернуть foo { 42, 42, 42 }, Я не вижу что explicit защищает меня от Я очень хочу { initializers... } синтаксис для обозначения «построить объект из заданных инициализаторов», и explicit встает на пути этого, спасая меня от ничего. (Поскольку { i } сводится к i в контексте инициализации копирования — большую часть времени — я с радостью откажусь от этого.)

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

46

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]