Question

Je voudrais définir dans une classe une constante dont la valeur est le int maximum. Quelque chose comme ceci:

class A
{
    ...
    static const int ERROR_VALUE = std::numeric_limits<int>::max();
    ...
}

Cette déclaration ne peut pas compiler avec le message suivant:

  

numeric.cpp: 8: Erreur: 'std :: numeric_limits :: max () ne peuvent pas apparaître dans une expression constante   numeric.cpp: 8: Erreur: un appel de fonction ne peut pas apparaître dans une expression constante

Je comprends pourquoi cela ne fonctionne pas, mais deux choses ont l'air étrange pour moi:

  1. Il me semble une décision naturelle d'utiliser la valeur dans les expressions constantes. Pourquoi les concepteurs de langue décident de faire max () une fonction ne permettant pas cet usage?

  2. Les revendications spec à 18.2.1 que

      

    Pour tous les membres déclarés const statique dans le modèle de numeric_limits, spécialisations définit ces valeurs de telle sorte qu'ils sont utilisables comme des expressions constantes intégrales.

    ne pas dire que je devrais pouvoir l'utiliser dans mon scénario et ne pas en contradiction avec le message d'erreur?

Merci.

Était-ce utile?

La solution

Alors que la norme actuelle manque de soutien ici, pour les types intégrés Boost.IntegerTraits vous donne les constantes de temps de compilation const_min et const_max.

Le problème provient de §9.4.2 / 4 :

  

Si un membre de données statique est de l'intégrale const ou type d'énumération const, sa déclaration dans la définition de la classe peut spécifier une initialiseur constante qui doit être une expression constante intégrale (5.19). Dans ce cas, le membre peut apparaître dans les expressions constantes intégrales.

Notez qu'il ajoute:

  

Le membre est défini encore dans un champ d'espace de noms si elle est utilisée dans le programme et la définition de la portée de l'espace de noms ne doit pas contenir un initialiseur.

Comme d'autres déjà mentionnés numeric_limits min() et max() sont tout simplement pas partie intégrante des expressions constantes, à savoir la compilation des constantes de temps.

Autres conseils

On dirait un peu un défaut ...

En C ++ 0x, numeric_limits aura tout marqué par constexpr, ce qui signifie que vous pourrez utiliser min() et max() comme des constantes de compilation.

Vous voulez:

#include <limits>

struct A {
static const int ERROR_VALUE;
}; 

const int A::ERROR_VALUE = std::numeric_limits<int>::max();

Mettre la classe / struct dans un en-tête et la définition dans un fichier .cpp.

Il ne contredit pas, parce que max n'est pas défini static const. Il est juste une fonction membre statique. Les fonctions ne peuvent être const, et les fonctions membres statiques ne peuvent pas avoir un const attaché à tout droit soit.

Il y a aussi un double max() dans la double version des limites, et en C ++ 03 cela ne fonctionnerait pas dire static double const max = .... Donc, pour être cohérent, max() est une fonction pour toutes les versions du modèle limite.

Maintenant, on sait que max() ne pas pouvoir être utilisé comme ce qui est mauvais, et C ++ 0x il résout déjà en en faisant une fonction constexpr, permettant à votre utilisation proposée.

  • Je vais essayer de vous répondre autant que je compris de votre question:

1- Si vous voulez un int const statique dans votre programme pour être initialisé avec une fonction:

int Data()
{
 return rand();
}

class A
{
public :
    static const int ee;
};
const int A::ee=Data();

Cela fonctionne sur VS 2008

2- Si vous voulez obtenir le nombre max et min pour un type de données, utilisez ces définitions INT_MAX, INT_MIN, LONG_MAX et ainsi de suite ..

3- Si toutefois vous devez utiliser ce type de modèle de WRT, puis coder en dur les modèles vous

template<>
int MaxData()
{
 return INT_MAX;
}

et

template<>
long MaxData()
{
 return LONG_MAX ;
}

et les appeler comme ça

int y=MaxData<int>();

4 et si vous ne traitez avec des types représentés binaires uniquement, utilisez ceci:

template <class T>
T MaxData(){
    return ~(1<<((sizeof(T)*8)-1));
}

et cette

template <class T>
T MinData(){
    return (1<<((sizeof(T)*8)-1));
}

Espérons que cela peut vous aider ..

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