2010-02-04 10 views
13

Ich möchte meine eigenen numerischen Typen, genau wie unsigned int, deklarieren, aber ich möchte nicht, dass die Typen implizit konvertiert werden. Ich habe das zuerst versucht: typedef unsigned int firstID; typedef unsigned int secondID;Deklarieren Sie Typen ohne implizite Konvertierung in C++

aber das ist nicht gut, da die beiden Typen nur Synonyme für unsigned int sind, also frei austauschbar sind.

Ich würde dies gerne einen Fehler verursachen:

firstID fid = 0; 
secondID sid = fid; // no implicit conversion error 

aber in Ordnung sein:

firstID fid = 0; 
secondID sid = static_cast<secondID>(fid); // no error 

Mein Grund ist, so dass die Funktionsargumente stark typisiert werden, zB:

void f(firstID, secondID); // instead of void f(unsigned int, unsigned int) 

Was ist der Mechanismus, den ich suche?

Dank

Si

+1

Kurz um die Typen tatsächliche Klassen oder Strukturen zu machen, gibt es keine Möglichkeit, dies zu tun. –

+0

Wurde das nicht schon gefragt? http://stackoverflow.com/questions/376452/enforce-strong-type-checking-in-c-type-strictness-for-typedefs – Manuel

Antwort

7

Vielleicht BOOST_STRONG_TYPEDEF Form boost/strong_typedef.hpp helfen würde.

+0

Macht Sinn, dass Boost das haben würde. Es ist keine Raketenwissenschaft, aber es ist eine Menge Arbeit, um alle Operatoren zu bekommen, und es verlangt nach einer Vorlage. –

+0

Ich liebe Boost. Hat immer eine Antwort – sipi

2

Sie haben eine eigene Klassen für sie zu schreiben, alle Betreiber Neuimplementierung Sie benötigen.

+0

Autsch, ich erwartete, dass es einfach zu sein! Schande, dass Sie nicht von einem unsigned Int erben können! – sipi

+2

Sie können die Klasse jedoch als Vorlage schreiben, sodass sie mindestens mit allen primitiven Typen funktioniert. – OregonGhost

1

Ahhh, ein Kerl Ada Reisender, den ich sehe.

Der einzige wirkliche Weg, dies in C++ zu tun, ist das Deklarieren von Klassen. Etwas wie:

class first_100 { 
public: 
    explicit first_100(int source) { 
     if (source < 1 || source > 100) { 
      throw range_error; 
     } 
     value = source; 
    }; 
    // (redefine *all* the int operators here) 
private: 
    int value; 
}; 

Sie wollen werden, um sicherzustellen, Ihr int-Konstruktor zu definieren explicit so dass C++ wird es nicht implizit zwischen Typen konvertieren verwenden. Auf diese Weise dies nicht funktionieren:

first_100 centum = first_100(55); 
int i = centum; 

aber so etwas wie dies könnte (vorausgesetzt, Sie es definieren):

int i = centum.to_int(); 
1
struct FirstID { int id; }; 
3

Wie Sie bemerkt: typedef schlecht (benannt wird, sollte es typealias sein (D hat explizit hinzugefügt typealias (letzte Mal sah ich))

So ist die einzige Art und Weise, dies zu tun ist, zwei zu schaffen einzigartige Klassen
Ich werde nicht sagen, dass Sie keine Spezialisierung von static_cast schreiben können <> zu tun, was Sie wollen, aber ich denke (und ich habe noch nicht viel darüber nachgedacht), dies zu tun wäre eine schlechte Idee (Auch wenn es legal ist), ich denke, ein besserer Ansatz besteht darin, dass jeder Klassenkonstruktor unsigned int verwendet, die explizit sind (es gibt also keine automatische Konvertierung.)

Wenn Sie den Konstruktor explizit machen, bedeutet dies keine automatische Konvertierung zwischen den Typen.
Durch das Hinzufügen des integrierten Cast-Operators zu unsigned int kann er überall dort verwendet werden, wo int int erwartet wird.

Verwandte Themen