O C ++ 20 introduziu explícito (bool) que seleciona condicionalmente em tempo de compilação se um construtor é explicitado ou não.
Abaixo está um exemplo que eu encontrei aqui .
struct foo {
// Specify non-integral types (strings, floats, etc.) require explicit construction.
template <typename T>
explicit(!std::is_integral_v<T>) foo(T) {}
};
foo a = 123; // OK
foo b = "123"; // ERROR: explicit constructor is not a candidate (explicit specifier evaluates to true)
foo c {"123"}; // OK
Alguém pode me dizer outro caso explicit (bool)
de uso que não seja o uso std::is_integral
?
tuple
com esse recurso.Respostas:
A motivação em si pode ser vista no artigo .
É necessário tornar os construtores condicionalmente explícitos. Ou seja, você quer:
O primeiro está bom, esses construtores estão implícitos. Mas o último seria ruim, esses construtores são
explicit
. Com o C ++ 17 (ou C ++ 20 com conceitos), a única maneira de fazer esse trabalho é escrever dois construtores - umexplicit
e um não:Estes são quase inteiramente duplicados - e as definições desses construtores seriam idênticas.
Com
explicit(bool)
, você pode simplesmente escrever um único construtor - com a parte condicionalmente explícita da construção localizada apenas noexplicit
especificador-:Isso combina melhor com a intenção, é muito menos código para escrever e é menos trabalhoso para o compilador durante a resolução de sobrecarga (já que há menos construtores para escolher).
fonte
enable_if_t
peça para uma restrição mais bonita e mais simples, possivelmente usando conceitos. Mas isso não vem ao caso desta questão.Outro uso possível que vejo é com o modelo variadic:
Geralmente é bom, por padrão, ter
explicit
um construtor com apenas um argumento (a menos que a conversão seja desejada).tão
fonte
Eu pude ver um caso de uso para exigir
explicit
condicionalmente quando a entrada pode ser do tipo de exibição (ponteiro brutostd::string_view
) , que o novo objeto manterá após a chamada (apenas copiando a exibição, não o que ela se refere, permanecendo dependente de a vida útil do objeto visualizado) ou pode ser do tipo valor (assume a propriedade de uma cópia, sem dependências externas da vida útil).Em uma situação como essa, o chamador é responsável por manter o objeto visualizado vivo (o receptor possui uma visualização, não o objeto original), e a conversão não deve ser feita implicitamente, porque facilita demais o objeto criado implicitamente. sobreviver ao objeto que vê. Por outro lado, para tipos de valor, o novo objeto receberá sua própria cópia; portanto, embora a cópia possa ser cara, ela não cometerá o código errado se ocorrer uma conversão implícita.
fonte