Marcar uma função como constexpr
também a torna uma função embutida § [dcl.constexpr] / 1:
Uma função ou membro de dados estático declarado com o especificador constexpr é implicitamente uma função ou variável embutida (7.1.6).
inline
, por sua vez, significa que você precisa incluir a definição dessa função em todas as unidades de tradução nas quais ela pode ser usada. Isso basicamente significa que as constexpr
funções devem ser:
- restrito ao uso em uma unidade de tradução, ou
- definido em um cabeçalho.
As funções mais comuns que você deseja declarar em um cabeçalho e definir em um arquivo de origem (e qualquer outra coisa que as use apenas inclui o cabeçalho e, em seguida, os links no arquivo de objeto dessa fonte) constexpr
simplesmente não funcionam.
Em teoria, suponho que você possa simplesmente mover tudo para os cabeçalhos e ter apenas um arquivo de origem que inclua todos os cabeçalhos, mas isso prejudicaria drasticamente o tempo de compilação e, para os projetos mais sérios, seria necessária uma quantidade imensa de memória para compilar.
Uma constexpr
função também é restrita em alguns aspectos, portanto, para algumas funções, pode não ser uma opção. As restrições incluem:
- funções virtuais não podem ser
constexpr
.
- seu tipo de retorno deve ser um 'tipo literal "(por exemplo, nenhum objeto com doutores ou dicionários não trival).
- todos os seus parâmetros devem ser tipos literais.
- o corpo da função não pode conter um
try
bloco.
- não pode conter uma definição variável de um tipo não literal ou qualquer coisa com duração de armazenamento estático ou de encadeamento.
Eu pulei algumas coisas obscuras (por exemplo, ela também não pode conter uma goto
ou uma asm
declaração), mas você entendeu - para algumas coisas, simplesmente não vai funcionar.
Conclusão: sim, existem algumas situações em que isso seria uma péssima idéia.