Quais são as regras pelas quais std::is_constructible
lida com construtores privados? Dado o seguinte código:
#include <iostream>
class Class {
private:
Class() { }
};
template <typename T>
class Test {
public:
static void test() {
std::cout
//<< std::is_constructible<Class>::value
<< std::is_constructible<T>::value
<< std::endl;
}
};
int main() {
Test<Class>::test();
}
Isso imprime 0
( ideona ), ou seja, T
não é construtível por padrão.
Descomentando a linha comentada, ela imprime 11
( ideona ) e, de T
repente, tornou-se padrão construtível.
Eu pude encontrar um raciocínio para apoiar os dois resultados, mas não entendo como a inclusão da linha comentada altera o resultado do segundo. Isso está de alguma forma invocando o UB? Isso é um bug do compilador? Ou é std::is_constructible
realmente tão inconsistente?
c++
typetraits
zennehoy
fonte
fonte
00
::value
versão é capaz de alterar a saída daqueles que vieram antes: godbolt.org/z/zCy5xU Descomente a linha comentada e tudo se torna 1: s no gcc.false
mas se o modelo da função não é comentado, ele retorna repentinamentetrue
: godbolt.org/z/zqxdk2Respostas:
std::is_constructible
deve retornarfalse
nesse cenário porque o construtor não está acessível.Conforme apontado abaixo da pergunta, o comportamento descrito na pergunta é causado por um bug no GCC / libstdc ++. O bug é relatado aqui e, de acordo com o Bugzilla, relacionado a se não é causado por um bug de controle de acesso para classes em funções de modelo que não foram resolvidas por um bom tempo. O relacionamento entre os dois bugs é retirado do comentário do Jonathan sobre o Bugzilla do Bugzilla, que parece ter detectado a conexão entre os dois bugs primeiro.
Isso também está implícito no fato de que o comportamento desse cenário no GCC se torna correto ao excluir o construtor em vez de torná-lo privado:
que imprime
0
e00
respectivamente. Esta é a saída correta (queclang
informa corretamente no cenário com um construtor privado também).Isso poderia explicar a mudança de comportamento observada ao comentar na linha, porque dentro da função na estrutura de modelo , a verificação de acesso não funciona e relata que o construtor está acessível quando não está. Quando a característica é verificada novamente na próxima linha ou possivelmente em um local completamente diferente (como é o caso aqui ), ela já foi instanciada e, portanto, produz a resposta errada.
fonte