Fazer um construtor com vários argumentos explicit
tem algum efeito (útil)?
Exemplo:
class A {
public:
explicit A( int b, int c ); // does explicit have any (useful) effect?
};
c++
explicit-constructor
Peter G.
fonte
fonte
explicit
. Eu pessoalmente não me incomodaria em fazer construtores multi-argexplicit
.Você tropeçaria nele para a inicialização da chave (por exemplo, em matrizes)
struct A { explicit A( int b, int c ) {} }; struct B { B( int b, int c ) {} }; int main() { B b[] = {{1,2}, {3,5}}; // OK A a1[] = {A{1,2}, A{3,4}}; // OK A a2[] = {{1,2}, {3,4}}; // Error return 0; }
fonte
As excelentes respostas de @StoryTeller e @Sneftel são o principal motivo. No entanto, IMHO, isso faz sentido (pelo menos eu faço isso), como parte da verificação futura de alterações posteriores no código. Considere seu exemplo:
class A { public: explicit A( int b, int c ); };
Este código não se beneficia diretamente de
explicit
.Algum tempo depois, você decide adicionar um valor padrão para
c
, então ele se torna este:class A { public: A( int b, int c=0 ); };
Ao fazer isso, você está se concentrando no
c
parâmetro - em retrospecto, ele deve ter um valor padrão. Você não está necessariamente focando seA
ele deve ser construído implicitamente. Infelizmente, essa mudança tornaexplicit
relevante novamente.Portanto, para transmitir que um ctor é
explicit
, pode valer a pena fazê-lo ao escrever o método pela primeira vez.fonte
explicit
que está lá há muito tempo, e o suporte técnico será inundado com ligações sobre essa mudança e passará horas explicando queexplicit
era apenas ruído e que removê-lo é inofensivo. Pessoalmente, não sou muito bom em prever o futuro; já é difícil decidir como uma interface deve ser agora .Aqui estão meus cinco centavos para esta discussão:
struct Foo { Foo(int, double) {} }; struct Bar { explicit Bar(int, double) {} }; void foo(const Foo&) {} void bar(const Bar&) {} int main(int argc, char * argv[]) { foo({ 42, 42.42 }); // valid bar({ 42, 42.42 }); // invalid return 0; }
Como você pode ver facilmente,
explicit
evita o uso da lista de inicializadores juntamente com abar
função porque o construtor destruct Bar
é declarado comoexplicit
.fonte