473,708 Members | 2,455 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

typedef of template classes are always default constructed?

Hello all. I have a simple question that seems trivial but I can't
make it to work. I have a class that takes as a template argument,
another class. The idea is as follows:

#include <iostream>

using namespace std;

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
}
};

class ClassB
{
int s_;

public:

ClassB(int s) : s_(s) {}
};

int main()
{
typedef ClassA<ClassBCA ;
CA ca;
ca.print();

return 0;
}

The thing is that when I try to compile this code, I receive the
message:
main2.cxx: In constructor 'ClassA<ClassB> ::ClassA()':
main2.cxx:7: error: no matching function for call to
'ClassB::ClassB ()'
main2.cxx:24: note: candidates are: ClassB::ClassB( int)
main2.cxx:19: note: ClassB::ClassB( const ClassB&)
main2.cxx: In function 'int main()':
main2.cxx:30: note: synthesized method 'ClassA<ClassB> ::ClassA()'
first required here

Of course because I don't provide a default constructor. If I change
within main() to something like

typedef ClassA<ClassB(6 )CA;

I receive the error:

main2.cxx: In function 'int main()':
main2.cxx:29: error: a call to a constructor cannot appear in a
constant-expression
main2.cxx:29: error: template argument 1 is invalid
main2.cxx:29: error: invalid type in declaration before ';' token
main2.cxx:31: error: request for member 'print' in 'ca', which
is of non-class type 'main::CA'

Furthermore, if I change the code to
ClassB cb(6);
typedef ClassA<cbCA;

I receive the same error. What am I doing wrong? I don't want the
class be to be default constructed within the type definition. Thanks
for your help.

aa

Nov 7 '06 #1
12 2321
aaragon wrote:
Hello all. I have a simple question that seems trivial but I can't
make it to work. I have a class that takes as a template argument,
another class. The idea is as follows:

#include <iostream>

using namespace std;

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
}
};

class ClassB
{
int s_;

public:

ClassB(int s) : s_(s) {}
};

int main()
{
typedef ClassA<ClassBCA ;
CA ca;
ca.print();

return 0;
}

The thing is that when I try to compile this code, I receive the
message:
main2.cxx: In constructor 'ClassA<ClassB> ::ClassA()':
main2.cxx:7: error: no matching function for call to
'ClassB::ClassB ()'
main2.cxx:24: note: candidates are: ClassB::ClassB( int)
main2.cxx:19: note: ClassB::ClassB( const ClassB&)
main2.cxx: In function 'int main()':
main2.cxx:30: note: synthesized method 'ClassA<ClassB> ::ClassA()'
first required here

Of course because I don't provide a default constructor. If I change
within main() to something like

typedef ClassA<ClassB(6 )CA;

I receive the error:

main2.cxx: In function 'int main()':
main2.cxx:29: error: a call to a constructor cannot appear in a
constant-expression
main2.cxx:29: error: template argument 1 is invalid
main2.cxx:29: error: invalid type in declaration before ';' token
main2.cxx:31: error: request for member 'print' in 'ca', which
is of non-class type 'main::CA'

Furthermore, if I change the code to
ClassB cb(6);
typedef ClassA<cbCA;

I receive the same error. What am I doing wrong? I don't want the
class be to be default constructed within the type definition. Thanks
for your help.
Templates can take types or (integral) constant expressions as
parameters, and these parameters must be available at *compile time*.
Creating an object instance like cb or ClassB(6) are both run-time
operations. You must either provide a default constructor (or a default
parameter on your existing constructor), or pass to ClassA<>'s
constructor the necessary parameters to initalize class B.

Cheers! --M

Nov 7 '06 #2

aaragon wrote:
Hello all. I have a simple question that seems trivial but I can't
make it to work. I have a class that takes as a template argument,
another class. The idea is as follows:

#include <iostream>

using namespace std;

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
}
};

class ClassB
{
int s_;

public:

ClassB(int s) : s_(s) {}
};

int main()
{
typedef ClassA<ClassBCA ;
CA ca;
ca.print();

return 0;
}

The thing is that when I try to compile this code, I receive the
message:
main2.cxx: In constructor 'ClassA<ClassB> ::ClassA()':
main2.cxx:7: error: no matching function for call to
'ClassB::ClassB ()'
main2.cxx:24: note: candidates are: ClassB::ClassB( int)
main2.cxx:19: note: ClassB::ClassB( const ClassB&)
main2.cxx: In function 'int main()':
main2.cxx:30: note: synthesized method 'ClassA<ClassB> ::ClassA()'
first required here

Of course because I don't provide a default constructor. If I change
within main() to something like

typedef ClassA<ClassB(6 )CA;

I receive the error:

main2.cxx: In function 'int main()':
main2.cxx:29: error: a call to a constructor cannot appear in a
constant-expression
main2.cxx:29: error: template argument 1 is invalid
main2.cxx:29: error: invalid type in declaration before ';' token
main2.cxx:31: error: request for member 'print' in 'ca', which
is of non-class type 'main::CA'

Furthermore, if I change the code to
ClassB cb(6);
typedef ClassA<cbCA;

I receive the same error. What am I doing wrong? I don't want the
class be to be default constructed within the type definition. Thanks
for your help.

aa
Whats preventing you from providing a default ctor in ClassB?

class ClassB
{
int s_;
public:
ClassB() : s_(0) { }
};

// or alternatively, one in ClassA:

template <class T>
class ClassA
{
int a;
T t;
public:
ClassA() : a(0), t(0) { }
void print() const { ... }
};

By the way, its never, never, a good idea _not_ to initialize ALL of
your members.
Even when these will be changed afterwards.

Nov 7 '06 #3


could anyone explain why the above program works if pointer is used ?

Nov 8 '06 #4
du************@ yahoo.dk wrote:
could anyone explain why the above program works if pointer is used ?
If a pointer is used where?

Cheers! --M

Nov 8 '06 #5

Salt_Peter wrote:
aaragon wrote:
Hello all. I have a simple question that seems trivial but I can't
make it to work. I have a class that takes as a template argument,
another class. The idea is as follows:

#include <iostream>

using namespace std;

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
}
};

class ClassB
{
int s_;

public:

ClassB(int s) : s_(s) {}
};

int main()
{
typedef ClassA<ClassBCA ;
CA ca;
ca.print();

return 0;
}

The thing is that when I try to compile this code, I receive the
message:
main2.cxx: In constructor 'ClassA<ClassB> ::ClassA()':
main2.cxx:7: error: no matching function for call to
'ClassB::ClassB ()'
main2.cxx:24: note: candidates are: ClassB::ClassB( int)
main2.cxx:19: note: ClassB::ClassB( const ClassB&)
main2.cxx: In function 'int main()':
main2.cxx:30: note: synthesized method 'ClassA<ClassB> ::ClassA()'
first required here

Of course because I don't provide a default constructor. If I change
within main() to something like

typedef ClassA<ClassB(6 )CA;

I receive the error:

main2.cxx: In function 'int main()':
main2.cxx:29: error: a call to a constructor cannot appear in a
constant-expression
main2.cxx:29: error: template argument 1 is invalid
main2.cxx:29: error: invalid type in declaration before ';' token
main2.cxx:31: error: request for member 'print' in 'ca', which
is of non-class type 'main::CA'

Furthermore, if I change the code to
ClassB cb(6);
typedef ClassA<cbCA;

I receive the same error. What am I doing wrong? I don't want the
class be to be default constructed within the type definition. Thanks
for your help.

aa

Whats preventing you from providing a default ctor in ClassB?
Well, I would like the user within main() to chose the required
paramter. For this class, a default parameter for this variable does
not make sense. I could initialize the variable to a default and
change it later on, but this is not very elegant. I thought that maybe
there was a way to do it at compile time.
class ClassB
{
int s_;
public:
ClassB() : s_(0) { }
};

// or alternatively, one in ClassA:

template <class T>
class ClassA
{
int a;
T t;
public:
ClassA() : a(0), t(0) { }
void print() const { ... }
};

By the way, its never, never, a good idea _not_ to initialize ALL of
your members.
Even when these will be changed afterwards.
Nov 8 '06 #6
aaragon wrote:
Salt_Peter wrote:
aaragon wrote:
Hello all. I have a simple question that seems trivial but I can't
make it to work. I have a class that takes as a template argument,
another class. The idea is as follows:
>
#include <iostream>
>
using namespace std;
>
template <class ClassB>
class ClassA
{
int a;
ClassB cb;
>
public:
>
void print(){
cout<<"print within class A"<<endl;
}
};
>
class ClassB
{
int s_;
>
public:
>
ClassB(int s) : s_(s) {}
};
>
int main()
{
typedef ClassA<ClassBCA ;
CA ca;
ca.print();
>
return 0;
}
>
The thing is that when I try to compile this code, I receive the
message:
main2.cxx: In constructor 'ClassA<ClassB> ::ClassA()':
main2.cxx:7: error: no matching function for call to
'ClassB::ClassB ()'
main2.cxx:24: note: candidates are: ClassB::ClassB( int)
main2.cxx:19: note: ClassB::ClassB( const ClassB&)
main2.cxx: In function 'int main()':
main2.cxx:30: note: synthesized method 'ClassA<ClassB> ::ClassA()'
first required here
>
Of course because I don't provide a default constructor. If I change
within main() to something like
>
typedef ClassA<ClassB(6 )CA;
>
I receive the error:
>
main2.cxx: In function 'int main()':
main2.cxx:29: error: a call to a constructor cannot appear in a
constant-expression
main2.cxx:29: error: template argument 1 is invalid
main2.cxx:29: error: invalid type in declaration before ';' token
main2.cxx:31: error: request for member 'print' in 'ca', which
is of non-class type 'main::CA'
>
Furthermore, if I change the code to
ClassB cb(6);
typedef ClassA<cbCA;
>
I receive the same error. What am I doing wrong? I don't want the
class be to be default constructed within the type definition. Thanks
for your help.
>
Whats preventing you from providing a default ctor in ClassB?

Well, I would like the user within main() to chose the required
paramter. For this class, a default parameter for this variable does
not make sense. I could initialize the variable to a default and
change it later on, but this is not very elegant. I thought that maybe
there was a way to do it at compile time.
So have ClassA accept a parameter for ClassB's constructor like I
suggested elsethread. This puts a requirement on all types used as a
template parameter to ClassA, but that's the way templates work.

Cheers! --M

Nov 8 '06 #7
mlimber wrote:
aaragon wrote:
Salt_Peter wrote:
aaragon wrote:
Hello all. I have a simple question that seems trivial but I can't
make it to work. I have a class that takes as a template argument,
another class. The idea is as follows:

#include <iostream>

using namespace std;

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
}
};

class ClassB
{
int s_;

public:

ClassB(int s) : s_(s) {}
};

int main()
{
typedef ClassA<ClassBCA ;
CA ca;
ca.print();

return 0;
}

The thing is that when I try to compile this code, I receive the
message:
main2.cxx: In constructor 'ClassA<ClassB> ::ClassA()':
main2.cxx:7: error: no matching function for call to
'ClassB::ClassB ()'
main2.cxx:24: note: candidates are: ClassB::ClassB( int)
main2.cxx:19: note: ClassB::ClassB( const ClassB&)
main2.cxx: In function 'int main()':
main2.cxx:30: note: synthesized method 'ClassA<ClassB> ::ClassA()'
first required here

Of course because I don't provide a default constructor. If I change
within main() to something like

typedef ClassA<ClassB(6 )CA;

I receive the error:

main2.cxx: In function 'int main()':
main2.cxx:29: error: a call to a constructor cannot appear in a
constant-expression
main2.cxx:29: error: template argument 1 is invalid
main2.cxx:29: error: invalid type in declaration before ';' token
main2.cxx:31: error: request for member 'print' in 'ca', which
is of non-class type 'main::CA'

Furthermore, if I change the code to
ClassB cb(6);
typedef ClassA<cbCA;

I receive the same error. What am I doing wrong? I don't want the
class be to be default constructed within the type definition. Thanks
for your help.

>
Whats preventing you from providing a default ctor in ClassB?
>
Well, I would like the user within main() to chose the required
paramter. For this class, a default parameter for this variable does
not make sense. I could initialize the variable to a default and
change it later on, but this is not very elegant. I thought that maybe
there was a way to do it at compile time.

So have ClassA accept a parameter for ClassB's constructor like I
suggested elsethread. This puts a requirement on all types used as a
template parameter to ClassA, but that's the way templates work.

Cheers! --M
I got it!!! There is another way. After reading chapter 2 of Modern
C++ Design (Alexandrescu) I found out that you can do this at compile
time. The solution is as follows:

#include <iostream>

using namespace std;

template<int v>
struct Int2Type
{
enum {value = v };
};

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
cout<<"print value s of class B: "<<cb.s()<<endl ;
}
};

template <class T>
class ClassB
{
int s_;

public:

ClassB() : s_(T::value) {}

int s() {return s_;}

};

int main()
{
typedef ClassA<ClassB<I nt2Type<4 CA;
CA ca;
ca.print();

return 0;
}

This works perfectly!!! Thank you guys.

aa

Nov 8 '06 #8
aaragon wrote:
I got it!!! There is another way. After reading chapter 2 of Modern
C++ Design (Alexandrescu) I found out that you can do this at compile
time. The solution is as follows:

#include <iostream>

using namespace std;

template<int v>
struct Int2Type
{
enum {value = v };
};

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
cout<<"print value s of class B: "<<cb.s()<<endl ;
}
};

template <class T>
class ClassB
{
int s_;

public:

ClassB() : s_(T::value) {}

int s() {return s_;}

};

int main()
{
typedef ClassA<ClassB<I nt2Type<4 CA;
CA ca;
ca.print();

return 0;
}

This works perfectly!!! Thank you guys.
Ok, now I see more clearly what you were trying to do. In the end, you
still provided a default constructor for ClassB, but the Int2Type in
your solution is unnecessary. Just make it:

template<int i>
class B
{
int s_;
public:
B() : s_(i) {}
};

In general, I'd prefer to use more conventional methods when they will
suffice:

template<class T>
class A
{
T t_;
public:
A( const T& t ) : t_(t) {}
};

class B
{
int s_;
public:
B( int s ) : s_(s) {}
};

void Foo()
{
B b( 6 );
A a( b );
// ...
}

Cheers! --M

Nov 8 '06 #9

mlimber wrote:
aaragon wrote:
I got it!!! There is another way. After reading chapter 2 of Modern
C++ Design (Alexandrescu) I found out that you can do this at compile
time. The solution is as follows:

#include <iostream>

using namespace std;

template<int v>
struct Int2Type
{
enum {value = v };
};

template <class ClassB>
class ClassA
{
int a;
ClassB cb;

public:

void print(){
cout<<"print within class A"<<endl;
cout<<"print value s of class B: "<<cb.s()<<endl ;
}
};

template <class T>
class ClassB
{
int s_;

public:

ClassB() : s_(T::value) {}

int s() {return s_;}

};

int main()
{
typedef ClassA<ClassB<I nt2Type<4 CA;
CA ca;
ca.print();

return 0;
}

This works perfectly!!! Thank you guys.

Ok, now I see more clearly what you were trying to do. In the end, you
still provided a default constructor for ClassB, but the Int2Type in
your solution is unnecessary. Just make it:

template<int i>
class B
{
int s_;
public:
B() : s_(i) {}
};

In general, I'd prefer to use more conventional methods when they will
suffice:

template<class T>
class A
{
T t_;
public:
A( const T& t ) : t_(t) {}
};

class B
{
int s_;
public:
B( int s ) : s_(s) {}
};

void Foo()
{
B b( 6 );
A a( b );
// ...
}

Cheers! --M
Thanks mlimber!

Nov 8 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2073
by: jack | last post by:
Hi there, I have a function F(x, y, z) and I want to calculate f(a) + f(b), where f(x) = F(x, x, z0) z0 is fixed. Suppose somebody wrote a routine called "Compute" which simply computes f(a) + f(b) for any one dimensional function f. Then I create a f1dim which converts any n-dimensional function
31
3511
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will return. I tried to write something like this: template <class Type1, class Type2, class Type3> Type3 findMin(Type1 x, Type2 y){ return (x < y) ? x : y;
7
3585
by: Paul | last post by:
Hi, I have a problem with the C++ spec 14.7.3.15 (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14761 for relevant discussion). It seems that the code (below) is impossible to get right, as you cannot define a static data member of a template class if it ONLY has a default-initializer...
7
483
by: Gurikar | last post by:
Does typedef vector<std::string> vNames; creates vector object?
7
2144
by: Tony Johansson | last post by:
Hello Experts! I have the following Array template class see below. I execute these three statements statement 1: Array<int> x(5); statement 2: cin >>x; statement 3: Array<int>::element_type y = x; but I can't understand the last one which is Array<int>::element_type y = x; We have a typedef T element_type; in the template Array class see below
5
2345
by: Hari | last post by:
Guys please help me to solve this strange problem what Iam getting as follows.. Trying to instantiate a global instance of a template class as follows :- when i build this code with debug and run this works fine. but if build in unicode release or release this does't work. IS THERE ANY PROBLEM OF INSTANTIATING TEMPLATE CLASSES
5
2137
by: Alan Woodland | last post by:
Hi, I don't think I can't do this directly with standard C++, I've tried all the ways I could think of that make sense and then some. I was wondering if someone had a genius idea how I could produce behavior, using standard C++, akin to what I guess can be best called a "typedef specializations". I.e. this being the default:
18
1926
by: Tom Cole | last post by:
I'm working on a small Ajax request library to simplify some tasks that I will be taking on shortly. For the most part everything works fine, however I seem to have some issues when running two requests at the same time. The first one stops execution as the second continues. If I place either an alert between the two requests or run the second through a setTimeout of only 1 millisecond, they both work. You can see a working example here:...
4
7942
by: alan | last post by:
AFAIK a template parameter must be completely determinable by the compiler at compile time, is this correct? Currently my problem is, I have a class which contains a std::vector. The size of this vector can be determined at the time an object of the class is constructed, and is assured not to change over the lifetime of the object. Now this class is part of an intrusive memory pool management scheme, and while it's okay for the...
0
8697
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9289
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9158
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7921
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6615
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5939
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
3151
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2508
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2096
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.