mit Templateargument Methoden "entfernen"?
-
Sone schrieb:
Ok, campers ist die Beste.
Ein einfaches
static_assertdürfte es schon tun
Bzw. Bei C++98/03 einfach
BOOST_REQUIRE_MESSAGE.Was soll
BOOST_REQUIRE_MESSAGEin dem Zusammenhang? Das ist aus Boost.Test und macht einen RUNTIME Check. Also vollkommen daneben.Wenn
static_assertnicht verfügbar ist nimmt man einfachBOOST_STATIC_ASSERT.
-
camper schrieb:
Was spricht gegen [static_assert]?
Das habe ich mir auch überlegt, war aber verunsichert, was den Auswertungszeitpunkt angeht.
Ist es also garantiert, dass
static_asserterst angeschaut wird, wenn die entsprechende Methode instanziiert wird?
-
Nexus schrieb:
Ist es also garantiert, dass
static_asserterst angeschaut wird, wenn die entsprechende Methode instanziiert wird?Nein. In diesem Falle ist aber die Bedingung vom Templateparameter abhängig und kann folglich erst bei der Instantiierung ausgewertet werden.
-
hustbaer schrieb:
Sone schrieb:
Ok, campers ist die Beste.
Ein einfaches
static_assertdürfte es schon tun
Bzw. Bei C++98/03 einfach
BOOST_REQUIRE_MESSAGE.Was soll
BOOST_REQUIRE_MESSAGEin dem Zusammenhang? Das ist aus Boost.Test und macht einen RUNTIME Check. Also vollkommen daneben.Ups.
Hab es nur einige Sekunden vorher benutzt, deswegen die Verwechselung :xmas2:Muss natürlich ~_STATIC_ASSERT sein.
-
camper schrieb:
Nexus schrieb:
Ist es also garantiert, dass
static_asserterst angeschaut wird, wenn die entsprechende Methode instanziiert wird?Nein. In diesem Falle ist aber die Bedingung vom Templateparameter abhängig und kann folglich erst bei der Instantiierung ausgewertet werden.
aber die sind doch in dem Moment vorhanden wo die Klasse instanziiert wird. Und zum Beispiel der gcc versucht dann jede Funktion zu instanziieren, selbst wenn sie nicht aufgerufen wird.
-
otze schrieb:
camper schrieb:
Nexus schrieb:
Ist es also garantiert, dass
static_asserterst angeschaut wird, wenn die entsprechende Methode instanziiert wird?Nein. In diesem Falle ist aber die Bedingung vom Templateparameter abhängig und kann folglich erst bei der Instantiierung ausgewertet werden.
aber die sind doch in dem Moment vorhanden wo die Klasse instanziiert wird. Und zum Beispiel der gcc versucht dann jede Funktion zu instanziieren, selbst wenn sie nicht aufgerufen wird.
Darf er das laut Standard überhaupt?
-
otze schrieb:
aber die sind doch in dem Moment vorhanden wo die Klasse instanziiert wird. Und zum Beispiel der gcc versucht dann jede Funktion zu instanziieren, selbst wenn sie nicht aufgerufen wird.
Sollte er eigentlich nicht, sofern es nicht eine explizite Instantiierung der Klasse oder aber die Funktion selbst virtuell ist.
-
<strong>N3337 §14.7.1 / 1</strong> schrieb:
The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions
Ist das der richtige Teil?
-
Sone schrieb:
<strong>N3337 §14.7.1 / 1</strong> schrieb:
The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions
Ist das der richtige Teil?
ja
template <bool R, bool W> struct X { void read() { static_assert( R, "read not enable for this type!" ); // ... } void write() { static_assert( W, "write not enable for this type!" ); // ... } bool is_open() const {}; }; X<false,false> a; X<false,true> b; X<true,false> c; X<true,true> d; //template struct X<false,false>; int main() {}wird anstandslos von g++ 4.3.6, 4.4.7, 4.5.4, 4.6.3, 4.7.2, 4.8.0 (20121216) und clang++ 3.2 kompiliert.
Eine explizite Instantiierung (außer <true,true>) oder die Deklaration als virtuelle Funktion führt dagegen zum Fehler.
-
Problem ist aber: wenn write() zB Schreibzugriff auf etwas vordert dass nur Schreibzugriff hat wenn W true ist - dann gibt es Fehler.
Deshalb gefaellt mir Nexus' Variante am besten - da sie flexibel ist.
Bei read/write koennte ich ja zB eine datei einmal als readonly, writeonly und einmal als read/write oeffnen wollen...
-
Ich verstehe das Problem nicht.
Ein einfaches "if (W)" im Konstruktor um den Open-Mode anzupassen sollte doch reichen.
write() kann doch eh nicht instanziert werden wenn W nicht true ist, also wo soll es da zu einem Problem kommen?
Vor allem verstehe ich nicht was die Basisklassen-Variante dabei besser machen/mehr können sollte.Ich steh grad ziemlich aufm Schlauch oder du hast dich vertan.
-
ich habe mich für die einfache static_assert Variante entschieden.
Eindeutig, einfach, gut
[Danke für das Brainstorming]