Ao marcar um construtor como excluído, ou seja
class MyClass {
// ...
MyClass(int x) = delete;
// ...
};
existe algum efeito em marcar o construtor excluído como explicit
? ou seja
explicit MyClass(int x) = delete;
?
Ao marcar um construtor como excluído, ou seja
class MyClass {
// ...
MyClass(int x) = delete;
// ...
};
existe algum efeito em marcar o construtor excluído como explicit
? ou seja
explicit MyClass(int x) = delete;
?
Sim,
= delete
não afeta a resolução de sobrecarga, exceto que se no final a resolução de sobrecarga escolher uma sobrecarga que seja excluída, então a resolução de sobrecarga será considerada mal formada.= delete
não modifica o processo de tomada de decisão para resolução de sobrecarga.explicit
afeta substancialmente a resolução de sobrecarga, pois altera se o construtor participará como candidato em diferentes cenários de resolução de sobrecarga.As duas construções são ortogonais. Um não implica que o outro deva ser adicionado ou eliminado.
Exemplo:
Sem
explicit
o primeiro construtor,MyClass x = 0;
está mal formado, pois a resolução de sobrecarga preferiria o primeiro construtor. Comexplicit
o primeiro construtor não é considerado para a inicialização da cópia e o segundo (que de outra forma seria uma correspondência pior) é escolhido. A inicialização não será malformada.Por outro lado, para uma inicialização do formulário
MyClass x(0);
, que é inicialização direta, todos os construtores são sempre considerados e a resolução de sobrecarga escolherá o primeiro, independentemente de serexplicit
ou não. Portanto esta inicialização será sempre mal formada.Portanto, neste exemplo, você precisa decidir se deseja fazer apenas conversão explícita de
int
mal formado (embora ainda permita a conversão implícita e explícita delong
) ou se deseja fazer conversão implícita e explícitalong
de mal formado.Mesmo que este seja o único construtor da classe, ainda há uma diferença.
Suponha que haja um conjunto de sobrecarga de função
com
Então tentar chamar
f(0)
fica bem formado, pois a primeira sobrecarga é inviável.explicit
construtores não são considerados para sequências de conversão implícitas para argumentos de função na resolução de sobrecarga. Somente a segunda sobrecarga é viável e será escolhida.Mas se não houver
explicit
, ambas as sobrecargas se tornarão viáveis e a resolução da sobrecarga será ambígua. O fato de o construtor ser excluído não importa para esta determinação.Excluir um construtor significa que você deseja que um resultado específico de resolução de sobrecarga faça com que a inicialização seja mal formada. Ao tomar a decisão de qual formulário deseja que fique mal formado, você sempre deve considerar se
explicit
deve ou não ser aplicado, assim como ao definir sobrecargas não excluídas.