How to call template constructor?
-
Here is the class with template constructor:
class C { private: int x; public: template<int X> C(void):x(X){;} };
How to call this constructor? This does not work:
C c<10>; C<10> c;
-
AFAIK it is not possible. But you can do something like this
class C { private: int x; C(int X) : x(X) {} public: template<int X> static C getC() { return C(X); } }; int main() { C elem(C::getC<2>()); return 0; }
-
That's right, constructors can't ever be called with template parameters. The only way of invoking such a constructor is by letting the compiler deduce the template arguments from the constructor arguments. This also means that a template constructor with no parameters can never be called at all.
-
Ok.
The question is: How I can pass a compile-time constant to the constructor?
The constant should still be the compile-time constant inside the constructor.
-
SAn schrieb:
Ok.
The question is: How I can pass a compile-time constant to the constructor?
The constant should still be the compile-time constant inside the constructor.also erstmal solltest du Deutsch lernen
-
^^^^^^, I decided to use German C++ forum for two reasons:
- It was at the first place in Google search (query "C++ Forum");
- I think German people are very "disciplined", so they should write the most correct (according to ANSI standard) C++ programs.
I do not know German language (I am from Russia). I decided that English will be OK. I can help beginner programmers here (I have perfect automatic translator from German to Russian), but I do no know if they know English.
I have been to Germany. There are beautiful places there:
http://keep4u.ru/imgs/b/071213/eb/ebd7c154670bae5fdf.jpg
http://www.photosight.ru/photo.php?photoid=2072575&ref=author
http://www.photosight.ru/photo.php?photoid=1721430&ref=author
-
Don't bother about the unregistered "Troll"
You could pass the constant via an empty pseudo-object that is an argument to the template-constructor (so the compiler can deduce the template argument from the real argument):
template< int N > struct value_t {}; class C { public: template< int N > C( value_t< N > ) { // access N } }; C c1( value_t< 12 >() ); C c2( value_t< 100 >() );
EDIT: Some optimizations.
-
LordJaxom, thanks a lot. This works for me.
-
Hi,
I was intrigued by the question so I tried to get the code to work. Obviously, I failed. However, I'd like to know *why* I failed.
Consider the following class and constructor:
struct C { int x; C() : x() { } };
Now, the following instantiation works on both MSVC 9 as well as GCC 4.2 and as far as I understand the standard, it's legal:
int main() { C c = C::C(); }
Analogously, I believe the following code should work; that is, I see no reason (in the standard or elsewhere) that it differs from the one above:
struct C { int x; template <int X> C() : x(X) { } }; int main() { C c = C::C<10>(); }
However, the code fails in both compilers. Here's what they say.
GCC: 'C' is not a template. No matching function for call to 'C::C()'
MSVC: 'C::{ctor}': cannot take address of this member functionCan anyone explain?
-
Konrad Rudolph schrieb:
Now, the following instantiation works on both MSVC 9 as well as GCC 4.2 and as far as I understand the standard, it's legal:
int main() { C c = C::C(); }
In german for Konrad:
Bei Sachen ob illegal oder nicht würde ich immer den Comeau zu rate ziehen: http://www.comeaucomputing.com/tryitout/ Einfach Code unten rein und "Compile"."ComeauTest.c", line 7: error: a constructor or destructor may not have its address taken C c = C::C();
Standard 12.1.12 schrieb:
No return type (not even void) shall be specified for a constructor. A return statement in the body of a constructor
shall not specify a return value. The address of a constructor shall not be taken.Im Falle C c = C(); erzeugst du ja im schlimmsten Fall ein temporäres Objekt das danach in c kopiert wird.
Wenn du schreibst C::C() bezeichnet man das glaube ich als einen "qualifizierten" Aufruf, d.h. du versuchst die Funktion( den Konstruktor ) direkt aufzurufen, was natürlich fehlschlägt.Zudem definiert man ja mit dem Ausdruck C::C() den C'tor außerhalb der Klasse, kann sein, dass das damit auch was zu tun hat.
[ Selbstgestrickte Theorie -> camper verbessert das schon ]
-
Selbstgestrickte Theorie -> camper verbessert das schon
ROFL
BTW: Wir sollten camper den Ehrentitel "C++ Standard Bot" geben (analog zu "Bible Bot" und ähnlichen Einrichtungen)
-
I have once learned that in C++ it is impossible to call any constructor directly, except via placement-new. Therefore, as I understand the standard, the first example should be illegal as well.
I think the quoted section of the standard confirms this, since you need an address for any function call (and since a constructor doesn't have a return value, it's result couldn't be used for an initialization anyways).
-
LordJaxom schrieb:
I have once learned that in C++ it is impossible to call any constructor directly, except via placement-new. Therefore, as I understand the standard, the first example should be illegal as well.
Yes, of course. KasF gave the correct explanation. Thanks to you both.