Seite 1 von 1

[C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 11:38
von DerAlbi
Huhu :oops:

Geht nicht:

Code: Alles auswählen

template<int N> struct SomeTemplate
{
	static const int n = N;
	int SomeMember;
};

void Test()
{
	SomeTemplate<5> foo;
	SomeTemplate<foo::n> bar;
}
was mein Ziel ist, sollte Selbsterklärend sein....

GCC (4.3.2):
'foo' cannot appear in a constant-expression
template argument 1 is invalid

WIe macht man das?

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 12:17
von DerAlbi
Ekelerregend. Aber läuft wenigstens durch...

Code: Alles auswählen

template<int N> struct SomeTemplate
{
static const char n[N];
int SomeMember;
};

void Test()
{
SomeTemplate<5> foo;
SomeTemplate<sizeof(foo.n)> bar;
}
Geht das auch ohne sinnlosen Speicherverbrauch? ;-)

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 13:10
von Krishty
SomeTemplate<decltype(foo)::n> bar?

Du versuchst, das Attribut einer Instanz zu übergeben, dabei musst du ein Attribut eines *Typs* übergeben. Darum meckert GCC.

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 13:31
von DerAlbi

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 14:47
von mnemonix
Hm, ich weiß zwar nicht für was du das brauchst, aber hier noch ein limitierter Workaround (N <= 0 funktioniert nicht, da Arrays bekanntlich größer Null sein müssen).

Code: Alles auswählen

template <int N>
struct SomeTemplate
{
    static const int n = N;
    int SomeMember;
};

template <typename T>
char (&SomeTemplate_GetN_(T)) [T::n];

#define SomeTemplate_GetN(x) sizeof(SomeTemplate_GetN_(x))

void Test()
{
    SomeTemplate<5> foo;
    SomeTemplate<SomeTemplate_GetN(foo)> bar;
}
Reicht denn nicht ein ganz normales typedef?

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 14:56
von DerAlbi
Mit welchem Compiler hast du das getestet?
Ich bekomme bei dir
error: size of array is not an integral constant-expression

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 15:15
von mnemonix
Getestet habe ich das unter VS2012 und http://gcc.godbolt.org/ (verschiedene Clangs und GCCs).

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 30.03.2015, 18:24
von Sternmull
Wenn n eine Konstante sein soll die zur Kompilier-Zeit bekannt sein soll, dann mach einen enum draus. Also "enum {n = N};" statt dem static const int. Das geht dann auch für negative Werte:

Code: Alles auswählen

template<int N> struct SomeTemplate
{
	enum {n = N};
	int SomeMember;
};

int main() {
	SomeTemplate<-5> foo;
	SomeTemplate<foo.n> bar;
	return 0;
}

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 01:22
von DerAlbi
Die enum-Methode liefert:
`.' cannot appear in a constant-expression
'foo' cannot appear in a constant-expression
invalid type in declaration before ';' token
http://ideone.com/kPqS2Y

Der Umweg über sizeof von mnemonix klappt doch. kA, was da der Fehler war. aber schön ist das nicht. Ich würde jetzt ungern über sizeof gehen...... das ist doch unfug!
Ist das echt so ein krasses problem?

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 03:19
von Gene
Es gibt noch den typeof operator (kein C++ standard) im gcc.

Code: Alles auswählen

template<int N> struct SomeTemplate
{
	static const int n = N;
	int SomeMember;
};

void Test()
{
	SomeTemplate<5> foo;
	typeof(foo) bar;
}

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 05:35
von DerAlbi
Korrekt, damit compiliert es sogar. Löst aber leider nicht mein Problem.
:oops: ...weil mein minimalbeispiel zu minimal war.... :oops:

Das Ganze ist für eine Festkomma-Template-Klasse. Das eigentliche Template hat mehere Parameter (Basistyp -> (unsigned) short / int, FractionalBits, KorrektesRunden)

Wenn ich jetzt z.B. a*8 rechne, benötige ich 3 Fractionalbits weniger im Ergebnis. Wenn ich es unabhängig von typeof(A) machen will, muss ich
Ergebnis<int, a::FracBits-3, ..> Ergenis = a * 8;

.......... :cry:

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 09:38
von Gene
In dem Fall sehe ich wenige Möglichkeiten, als über einen Array-Hack, wie Du bereits vorgeschlagen hast.
Man kann das natürlich geschickt in eine Funktion stecken, so das man den Speicherplatz nicht "verbraucht".

Code: Alles auswählen

template<int N> struct Size
{
	char _[N];
};
template<int N> struct SomeTemplate
{
	Size<N> size() { return Size<N>(); }
    int SomeMember;
};

int main() {
        SomeTemplate<5> foo;
        SomeTemplate<sizeof(foo.size())> bar;
        return 0;
}

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 11:24
von DerAlbi
Jo, compiliert! :roll:
schön isses nicht :cry:

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 12:21
von Spiele Programmierer
Warum benutzt du nicht C++11?
Dann wäre es auch sehr schön.

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 12:43
von DerAlbi
...erster Post: GCC (4.3.2)
Ich compiliere leider nicht für x86... und auch nicht für ARM. Man ist da auf die Chip-Hersteller angewiesen, dass die die Toolchain mal updaten.. aber hey... wozu -.-
C++ wird für Mikrocontroller eh meist als "uninteressant" abgetan... und solang sich bei C nix ändert..... bäääh.
Wäre ja traumhaft, wenn man das selbst irgendwie hinbekommen würde.. aber den GCC anrühren? *hust*

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 12:56
von Sternmull
DerAlbi hat geschrieben:Die enum-Methode liefert:
`.' cannot appear in a constant-expression
'foo' cannot appear in a constant-expression
invalid type in declaration before ';' token
http://ideone.com/kPqS2Y
Hatte es nur mit C++14 ausprobiert, dort geht es. Für C++03 müsste man "SomeTemplate<-5>::n" statt "foo.n" schreiben, sich also explizit auf den Typen beziehen. Wenn das keine Option ist, dann bleibt immer noch BOOST_TYPEOF, z.B. so hier.

Re: [C++] Template-Parameter als Template-Parameter

Verfasst: 31.03.2015, 20:25
von DerAlbi
Das ist für den GCC nichts weiter als das normale typeof. Das funktioniert, wenn man dafür eine extra Zeile anlegt... typeof funtkioniert aber nicht innerhalb der < > Klammern :-(
ist schon ok. es it lößbar, wird aber niemals zum erwünschten einzeiler mit direkter nutzung der variable und eines attributs auch was das alles compile-time konstant ist. wieso auch immer.... ich will nen neuen gcc! würd auch gern mal mit den neueren standards arbeiten.. :(