Question

I essayé d'écrire une fonction qui renvoie un nombre entier avec seulement le bit le plus élevé de l'ensemble d'entrée, en utilisant un C ++ 0x constexpr.

constexpr inline uint64_t
get_highest_bit(uint64_t p)
{
  return 
     (p|=(p>>1)),
     (p|=(p>>2)),
     (p|=(p>>4)),
     (p|=(p>>8)),
     (p|=(p>>16)),
     (p|=(p>>32)),
     (p-(p>>1));
}

Cela donne un échec de la compilation avec gcc 4.6.1.

error: expression ‘(p <unknown operator> ((p >> 1) | p))’ is not a constant-expression

Notez que cela fonctionne sans le mot clé constexpr.

Mes questions sont les suivantes:

Pourquoi cela ne fonctionne pas? Je peux voir que l'opérateur | = est pas constexpr, mais est-il important pour les types intégrés

?

Yat-il un moyen facile d'écrire cette fonction comme constexpr? Je voudrais qu'il soit efficace raisonnable lors de l'exécution, et je me soucie un peu readibility.

Était-ce utile?

La solution

(non testé sur GCC parce que je n'ai pas 4,6, mais je l'ai vérifié que l'algorithme est correct.)

Pour utiliser constexpr vous ne devez pas avoir des missions. Par conséquent, vous avez souvent à écrire dans fonction formulaire avec récursion:

#include <cstdint>
#include <climits>

constexpr inline uint64_t highestBit(uint64_t p, int n = 1) {
    return n < sizeof(p)*CHAR_BIT ? highestBit(p | p >> n, n * 2) : p - (p >> 1);
}

int main() {
    static_assert(highestBit(7) == 4);
    static_assert(highestBit(5) == 4);
    static_assert(highestBit(0x381283) == 0x200000);
    return 0;
}

Vous pouvez vérifier C ++ 0x § [expr.const] / 2 pour voir ce que les expressions ne peuvent pas être utilisées dans une fonction constexpr. En particulier, l'avant-dernier élément est « une cession ou une cession composé ».

Autres conseils

constexpr inline uint64_t highestBit(uint64_t p)
{
    return (p & (p-1))? highestBit(p & (p-1)): p;
}

Chaque niveau de récursivité efface le bit le plus à droite qui a été réglée, lorsque le bit final serait effacé, seul le bit est resté, il est donc retourné.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top