Традиционно считается, что конструкторы, принимающие один параметр (явно или эффективно за счет использования параметров по умолчанию), должны быть помечены 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
для унарных конструкторов, и только для них.
person
Luc Danton
schedule
15.09.2012