Frage

Ich möchte in einer Klasse eine Konstante definieren, welcher Wert ist die maximal mögliche int. So etwas wie folgt aus:

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

Diese Erklärung schlägt mit der folgenden Meldung zu kompilieren:

numeric.cpp: 8: Fehler: 'std :: numeric_limits :: max ()' erscheinen nicht in einem konstanten Ausdruck numeric.cpp: 8: Fehler: ein Funktionsaufruf kann nicht in einem konstanten Ausdruck erscheint

Ich verstehe, warum dies nicht funktioniert, aber zwei Dinge sehen seltsam zu mir:

  1. Es scheint mir eine natürliche Entscheidung, den Wert in konstanten Ausdrücken zu verwenden. Warum haben die Sprachdesigner zu machen max () eine Funktion also nicht diese Nutzung erlaubt?

  2. Die spec Ansprüche in 18.2.1, dass

    Für alle Mitglieder static const in der numeric_limits Vorlage erklärt, Spezialisierungen sind diese Werte so definieren, dass sie als integrale Konstante Ausdrücke verwendbar sind.

    es bedeutet nicht, dass ich in der Lage sein sollte, es in meinem Szenario zu verwenden, und es widerspricht nicht die Fehlermeldung?

Danke.

War es hilfreich?

Lösung

Während der aktuelle Standard fehlt Unterstützung hier, für integrale Typen Boost.IntegerTraits die Kompilierung gibt Konstanten const_min und const_max.

Das Problem ergibt sich aus §9.4.2 / 4 :

Wenn ein statisches Datenelement von const integral ist oder const Aufzählungstyp, ihre Erklärung in der Klassendefinition kann einen Konstant Initialisierer angeben, die ein integraler konstanter Ausdruck sein werden (5,19). In diesem Fall kann das Element in integraler konstanter Ausdrücke erscheinen.

Beachten Sie, dass es fügt hinzu:

Das Mitglied wird nach wie vor in einem Namespace Bereich definiert werden, wenn sie im Programm verwendet wird und die Namespacebereich Definition stellt keinen Initialisierer enthält.

Wie andere bereits erwähnt numeric_limits min() und max() ist einfach nicht integral konstantes Ausdrücke, das heißt die Kompilierung Konstanten.

Andere Tipps

Sieht aus wie ein bisschen ein Defekt ...

In C ++ 0x, wird numeric_limits alles mit constexpr markiert hat, was bedeutet, Sie in der Lage sein werden, min() und max() als Kompilierung-Konstanten zu verwenden.

Sie möchten:

#include <limits>

struct A {
static const int ERROR_VALUE;
}; 

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

Setzen Sie die Klasse / Struktur in einem Header und die Definition in einer CPP-Datei.

Es steht nicht im Widerspruch, weil max static const nicht definiert ist. Es ist nur eine statische Member-Funktion. Funktionen können nicht const sein und statische Elementfunktionen können keine const an ganz rechts entweder angebracht haben.

Es gibt auch eine double max() in der doppelten Version der Grenzen, und in C ++ 03 wäre es nicht static double const max = ... sagen arbeiten. So konsequent zu sein, ist max() eine Funktion für alle Versionen der Grenze Vorlage.

Nun, es ist bekannt, dass max() nicht in der Lage ist, so verwendet wird, ist schlecht, und C ++ 0x löst es bereits durch eine constexpr Funktion zu machen, Ihre vorgeschlagene Nutzung ermöglicht.

  • Ich werde versuchen, Ihnen so viel zu beantworten, wie ich aus Ihrer Frage verstanden:

1- Wenn Sie ein statisches const int in Ihrem Programm wollen mit einer Funktion initialisiert werden:

int Data()
{
 return rand();
}

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

Dies funktioniert auf VS 2008

2- Wenn Sie für einen bestimmten Datentyp max und min Zahl zu erhalten, dann diese Definitionen verwenden INT_MAX, INT_MIN, LONG_MAX und so weiter ..

3- Wenn Sie jedoch benötigen, diesen wrt Vorlagentyp verwenden, dann Fest Code die Vorlagen selbst

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

und

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

und sie so nennen

int y=MaxData<int>();

4- und wenn Sie nur mit binären dargestellten Typen zu tun, so verwenden:

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

und das

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

Hope dies kann Ihnen helfen ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top