web-dev-qa-db-fra.com

variable statique constexpr vs fonction

Existe-t-il une différence entre déclarer une constante à virgule flottante comme static constexpr variable et une fonction comme dans l'exemple ci-dessous, ou est-ce juste une question de style?

class MY_PI
{
public:
    static constexpr float MY_PI_VAR = 3.14f;
    static constexpr float MY_PI_FUN() { return 3.14f; }
}
55
user2052436

constexpr fonctions

Les fonctions ont un avantage que les variables libres n'ont pas (jusqu'à C++ 14 c'est-à-dire): elles peuvent facilement être modélisées sans un passe-partout de classe. Cela signifie que vous pouvez avoir votre pi avec une précision en fonction d'un argument de modèle:

template<typename T>
constexpr T pi();

template<>
constexpr float pi() { return 3.14f; }

template<>
constexpr double pi() { return 3.1415; }

int main()
{
    constexpr float a = pi<float>();
    constexpr double b = pi<double>();
}

Cependant, si vous décidez d'utiliser une fonction membre static au lieu d'une fonction gratuite, elle ne sera pas plus courte ni plus facile à écrire qu'une variable membre static.

constexpr variables

Le principal avantage de l'utilisation d'une variable est que ... eh bien. Vous voulez une constante, non? Il clarifie l'intention et cela peut être l'un des points les plus importants ici.

Vous pouvez toujours avoir un comportement équivalent avec une classe, mais vous devez alors l'utiliser comme ceci si votre classe est une classe contenant diverses constantes mathématiques:

constexpr float a = constants<float>::pi;

Ou comme ceci si votre classe est uniquement destinée à représenter pi:

constexpr double = pi<double>::value;

Dans le premier cas, vous préférerez peut-être utiliser des variables car elles seront plus courtes à écrire et cela montrera vraiment que vous utilisez une constante et n'essayez pas de calculer quelque chose. Si vous avez juste une classe représentant pi, vous pouvez cependant opter pour une fonction libre constexpr au lieu d'une classe entière. Ce serait à mon humble avis plus simple.

C++ 14: constexpr modèles de variables

Cependant, notez que si vous choisissez d'utiliser C++ 14 au lieu de C++ 11, vous pourrez écrire le type suivant de modèles de variable constexpr:

template<typename T>
constexpr T pi = T(3.1415);

Cela vous permettra d'écrire votre code comme ceci:

constexpr float a = pi<float>;

À partir de C++ 14, cela peut être la façon préférée de faire les choses. Si vous utilisez une ancienne version de la norme, les deux premiers paragraphes sont toujours valables.

54
Morwenn