Eu provavelmente nunca diria nunca, mas as instruções que geram dados e código à medida que são analisadas não devem estar em um arquivo .h.
Macros, funções embutidas e modelos podem parecer dados ou código, mas não geram código à medida que são analisados, mas quando são usados. Esses itens geralmente precisam ser usados em mais de um .c ou .cpp, para que pertençam ao .h.
Na minha opinião, um arquivo de cabeçalho deve ter a interface prática mínima para um correspondente .c ou .cpp. A interface pode incluir #defines, classe, typedef, definições de estrutura, protótipos de função e definições externas menos preferidas para variáveis globais. No entanto, se uma declaração for usada em apenas um arquivo de origem, provavelmente ela deve ser excluída do arquivo .he deve estar contida no arquivo de origem.
Alguns podem discordar, mas meu critério pessoal para arquivos .h é que eles #incluem todos os outros arquivos .h que precisam ser capazes de compilar. Em alguns casos, pode haver muitos arquivos, portanto, temos alguns métodos eficazes para reduzir dependências externas, como declarações de encaminhamento para classes, que permitem usar ponteiros para objetos de uma classe sem incluir o que poderia ser uma grande árvore de arquivos de inclusão.