Pergunta

De acordo com Sergey Ryazanov, seu Delegados C++ incrivelmente rápidos não são comparáveis:

Meus delegados não podem ser comparados.Os operadores de comparação não são definidos porque um delegado não contém um ponteiro para o método.O ponteiro para uma função stub pode ser diferente em várias unidades de compilação.

Ao qual os leitores responderam:

"O ponteiro para uma função de stub pode ser diferente em várias unidades de compilação". Afaik, isso não é verdade.Os compiladores são obrigados a reutilizar funções de modelo geradas em diferentes unidades de compilação (disso eu tenho certeza - mas acho que a Borland uma vez violou essa regra).Eu acho que é porque as classes (aquelas que não estão em namespaces 'sem nome') usam ligação externa e a maneira como você usa as funções stub sempre impedirá que elas sejam embutidas (embora isso também não deva ser um problema, pois pega o endereço da função forçará a geração de uma versão não inline e a 'ligação externa' executada pelo vinculador eliminará todas as funções, exceto uma com nome semelhante (elas são assumidas e exigidas como idênticas pelo padrão)) ...

Se você definir uma função de modelo em uma unidade de tradução (arquivo cpp) e depois definir a mesma função de maneira diferente em outra unidade de tradução, apenas uma das duas versões chegará ao executável final.(Isso realmente viola a "Regra de Uma Definição", mas funciona no GCC, pelo menos...não tenho certeza sobre MSVC.) A questão é:o endereço [do stub] será o mesmo em unidades diferentes.

Recomendo que você atualize o artigo (incluindo capacidade de comparação) se achar que isso é verdade para o MSVC - se o MSVC for uma atribuição de padrões, nesse sentido.

Agora, o artigo tem quatro anos e o autor não respondeu a nenhum dos comentários durante os últimos três anos, então estou me perguntando se há algum mérito no comentário acima e se esta implementação específica pode realmente ser alterada para apoiar comparações.

O padrão C++ proíbe especificamente tal uso e, em caso afirmativo, algum dos compiladores recentes é realmente compatível com o padrão nesse sentido?

Foi útil?

Solução

O código é compatível com padrão e é bom. Não vejo nenhum lugar onde ele viole o ODR, e é verdade que todas as instanciais de um modelo de função com os mesmos parâmetros de modelo devem ter "o mesmo endereço" (em certo sentido que os ponteiros para funções devem ser iguais) - como Isso é alcançado não é importante. ISO C ++ 03 14.5.5.1 [temp.over.link] descreve as regras com mais detalhes.

Portanto, uma comparação poderia muito bem ser definida lá de uma maneira conformante e portátil.

Outras dicas

O assim chamado esboço funções em Delegados C++ incrivelmente rápidos são funções de membro de modelo estático, que são basicamente funções de modelo.O mesmo se aplica à variante melhorada Delegados C++ incrivelmente rápidos, corrigidos.

Então a questão se resume a isto:

As instanciações de uma função de modelo (usando os mesmos parâmetros e definições de modelo) em diferentes unidades de tradução compartilham o mesmo endereço de ponteiro de função?

De acordo com o padrão C++ (ISO C++17, § 17.5.6.1), a resposta é sim.

Como @Pavel disse em sua resposta, o mesmo se aplica ao padrão ISO C++ 03 (ISO C++ 03, § 14.5.5.1).

Em outras palavras, esta abordagem é compatível com o padrão e os delegados são comparáveis ​​com segurança - seus dados são comparados iguais se e somente se eles estiverem vinculados à mesma função e (no caso de funções-membro) ao mesmo objeto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top