473,383 Members | 1,837 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Template parameters in constructor

I've got a 'Command' class whose constructor takes an instance of a
template argument T. The constructor then prints out the name of the
class T that was passed to it. When I construct the T class in advance
of instantiating Command, it works. When I construct the T class *in*
the Command constructor, it doesn't work. Any ideas?

================ CODE FOLLOWS ===============

#include <iostream>

class Command
{
public:

template<class T> explicit Command(T & t)
{
std::cout << typeid(T).name() << std::endl;
}
};

class Bar { };

int main()
{
Bar b;
Command cmd(b); // This works
Command cmd2(Bar()); // This doesn't

return 0;
}

Jul 23 '05 #1
17 1994
mrstephengross wrote:
I've got a 'Command' class whose constructor takes an instance of a
template argument T. The constructor then prints out the name of the
class T that was passed to it. When I construct the T class in advance
of instantiating Command, it works. When I construct the T class *in*
the Command constructor, it doesn't work. Any ideas?

================ CODE FOLLOWS ===============

#include <iostream>

class Command
{
public:

template<class T> explicit Command(T & t)
{
std::cout << typeid(T).name() << std::endl;
}
};

class Bar { };

int main()
{
Bar b;
Command cmd(b); // This works
Command cmd2(Bar()); // This doesn't
It's a declaration of a function. Read about it in the archives.
It's a well-known trap for beginners, which curiously enough sometimes
works for seasoned C++ programmers.

return 0;
}


V
Jul 23 '05 #2
Interesting; I'll look it up... Is there a correct syntax for the kind
of instantiation I'm trying to invoke?

--Steve

Jul 23 '05 #3
On Fri, 17 Jun 2005 18:15:56 +0400, mrstephengross
<mr************@hotmail.com> wrote:
I've got a 'Command' class whose constructor takes an instance of a
template argument T. The constructor then prints out the name of the
class T that was passed to it. When I construct the T class in advance
of instantiating Command, it works. When I construct the T class *in*
the Command constructor, it doesn't work. Any ideas?
Please state clearly what it means "it works" and "id does not work". If
your compiler produces error messages provide them with your question.
================ CODE FOLLOWS ===============

#include <iostream>

class Command
{
public:

template<class T> explicit Command(T & t)
{
std::cout << typeid(T).name() << std::endl;
}
};

class Bar { };

int main()
{
Bar b;
Command cmd(b); // This works
Command cmd2(Bar()); // This doesn't

return 0;
}


In the "This doesn't" case you create a temporary object. A temporary
object is an r-value. R-value can not be bound to a reference to a
non-const. To fix the error make your templated constructor accept either
T by value (T t) or by reference to const (T const& t).
--
Maxim Yegorushkin
Jul 23 '05 #4

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Ey*****************@newsread1.mlpsca01.us.to. verio.net...
mrstephengross wrote:
I've got a 'Command' class whose constructor takes an instance of a
template argument T. The constructor then prints out the name of the
class T that was passed to it. When I construct the T class in advance
of instantiating Command, it works. When I construct the T class *in*
the Command constructor, it doesn't work. Any ideas?

================ CODE FOLLOWS ===============

#include <iostream>

class Command
{
public:

template<class T> explicit Command(T & t)
{
std::cout << typeid(T).name() << std::endl;
}
};

class Bar { };

int main()
{
Bar b;
Command cmd(b); // This works
Command cmd2(Bar()); // This doesn't


It's a declaration of a function. Read about it in the archives.
It's a well-known trap for beginners, which curiously enough sometimes
works for seasoned C++ programmers.


Eh? What in that last line is a declaration of a function?

The only problem is that Bar() returns a temporary, which can't bind to a
non-const reference. But that should produce a compile error. Steve says
it doesn't work, but he doesn't say what *does* happen. Once I correct the
const-ness of the T& parameter, it compiles fine, and produces the correct
output ("class Bar") in both cases.

-Howard


Jul 23 '05 #5
Howard wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Ey*****************@newsread1.mlpsca01.us.to. verio.net...
mrstephengross wrote:
I've got a 'Command' class whose constructor takes an instance of a
template argument T. The constructor then prints out the name of the
class T that was passed to it. When I construct the T class in advance
of instantiating Command, it works. When I construct the T class *in*
the Command constructor, it doesn't work. Any ideas?

================ CODE FOLLOWS ===============

#include <iostream>

class Command
{
public:

template<class T> explicit Command(T & t)
{
std::cout << typeid(T).name() << std::endl;
}
};

class Bar { };

int main()
{
Bar b;
Command cmd(b); // This works
Command cmd2(Bar()); // This doesn't
It's a declaration of a function. Read about it in the archives.
It's a well-known trap for beginners, which curiously enough sometimes
works for seasoned C++ programmers.

Eh? What in that last line is a declaration of a function?


The statement. You know, the part between the beginning of the line and
the closing semicolon.
The only problem is that Bar() returns a temporary, which can't bind to a
non-const reference. But that should produce a compile error. Steve says
it doesn't work, but he doesn't say what *does* happen. Once I correct the
const-ness of the T& parameter, it compiles fine, and produces the correct
output ("class Bar") in both cases.


REALLY?? On what compiler?

This:
---------------------------------------------
struct A {
template<class T> explicit A(T const& t);
int foo();
};

struct B {};

int main() {
A a(B());
return a.foo();
}
---------------------------------------------
does not compile. Now, you tell me why.

V
Jul 23 '05 #6

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Uz****************@newsread1.mlpsca01.us.to.v erio.net...
Howard wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Ey*****************@newsread1.mlpsca01.us.to. verio.net...
mrstephengross wrote:

I've got a 'Command' class whose constructor takes an instance of a
template argument T. The constructor then prints out the name of the
class T that was passed to it. When I construct the T class in advance
of instantiating Command, it works. When I construct the T class *in*
the Command constructor, it doesn't work. Any ideas?

================ CODE FOLLOWS ===============

#include <iostream>

class Command
{
public:

template<class T> explicit Command(T & t)
{
std::cout << typeid(T).name() << std::endl;
}
};

class Bar { };

int main()
{
Bar b;
Command cmd(b); // This works
Command cmd2(Bar()); // This doesn't

It's a declaration of a function. Read about it in the archives.
It's a well-known trap for beginners, which curiously enough sometimes
works for seasoned C++ programmers.
Eh? What in that last line is a declaration of a function?


The statement. You know, the part between the beginning of the line and
the closing semicolon.


I know that this is a function declaration:

Command cmd();

But this:

Command cmd(Bar());

couldn't be a function declaration. It would be a syntax error if it were,
since the parameter "Bar()" makes no sense. Perhaps you're thinking of
this:

Command cmd(Bar);

? In that case, the parameter is an object of type Bar, so it's a legal
function declaration. Not so in the given case.
The only problem is that Bar() returns a temporary, which can't bind to a
non-const reference. But that should produce a compile error. Steve
says it doesn't work, but he doesn't say what *does* happen. Once I
correct the const-ness of the T& parameter, it compiles fine, and
produces the correct output ("class Bar") in both cases.


REALLY?? On what compiler?


VC++ 2003 (version 7), (with "languages extensions disabled", so that it
doesn't allow silly non-standard things like the non-const-ness of the
reference parameter).

This:
---------------------------------------------
struct A {
template<class T> explicit A(T const& t);
int foo();
};

struct B {};

int main() {
A a(B());
return a.foo();
}
---------------------------------------------
does not compile. Now, you tell me why.

V


It compiles fine. It fails to link, because neither the constructor nor the
function foo are defined. Once I add the bodies for those, it works fine.
What compiler does it fail on, and with what message?

-Howard

Jul 23 '05 #7

"Howard" <al*****@hotmail.com> wrote in message
news:eQ********************@bgtnsc04-news.ops.worldnet.att.net...

Well, this is interesting. I just double-checked the FAQ [10.19], and found
that you're right. Well, you're right in how that *should* be treated.
Looks like VC++ isn't following the rules. I don't have the standard to
check on the legalese, but I tend to trust the FAQ on such things, and it
describes precisely why that line should be considered a function
declaration. I guess Microsquish felt they had a better plan. :-)

Thanks for the info, Victor.

-H
Jul 23 '05 #8
Howard wrote:

This:
---------------------------------------------
struct A {
template<class T> explicit A(T const& t);
int foo();
};

struct B {};

int main() {
A a(B());
return a.foo();
}
---------------------------------------------
does not compile. Now, you tell me why.

V


It compiles fine. It fails to link, because neither the constructor nor the
function foo are defined. Once I add the bodies for those, it works fine.
What compiler does it fail on, and with what message?

-Howard


It didn't compile for me on MSVC 2003 version 7.1.3088. Here's the
code I tried:

struct A {
template<class T> explicit A(T const& t) {};
int foo() {return 1;}

};

struct B {};

int main() {
A a(B());
return a.foo;
}

....and here's the compiler output:

------ Build started: Project: stuff, Configuration: Debug Win32 ------

Compiling...
stuff.cpp
x:\work\stuff\stuff.cpp(12) : error C2228: left of '.foo' must have
class/struct/union type
type is 'overloaded-function'

Build log was saved at "file://x:\work\stuff\Debug\BuildLog.htm"
stuff - 1 error(s), 0 warning(s)

Take care,

John Dibling

Jul 23 '05 #9
Howard wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Uz****************@newsread1.mlpsca01.us.to.v erio.net...
Howard wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Ey*****************@newsread1.mlpsca01.us. to.verio.net...
mrstephengross wrote:
>I've got a 'Command' class whose constructor takes an instance of a
>template argument T. The constructor then prints out the name of the
>class T that was passed to it. When I construct the T class in advance
>of instantiating Command, it works. When I construct the T class *in*
>the Command constructor, it doesn't work. Any ideas?
>
>================ CODE FOLLOWS ===============
>
>#include <iostream>
>
>class Command
>{
>public:
>
> template<class T> explicit Command(T & t)
> {
> std::cout << typeid(T).name() << std::endl;
> }
>};
>
>class Bar { };
>
>int main()
>{
> Bar b;
> Command cmd(b); // This works
> Command cmd2(Bar()); // This doesn't

It's a declaration of a function. Read about it in the archives.
It's a well-known trap for beginners, which curiously enough sometimes
works for seasoned C++ programmers.

Eh? What in that last line is a declaration of a function?
The statement. You know, the part between the beginning of the line and
the closing semicolon.

I know that this is a function declaration:

Command cmd();

But this:

Command cmd(Bar());

couldn't be a function declaration.


Couldn't? Yet it is.
It would be a syntax error if it were,
since the parameter "Bar()" makes no sense. Perhaps you're thinking of
this:

Command cmd(Bar);
No, I am not thinking of that. It is a function declaration.
? In that case, the parameter is an object of type Bar, so it's a legal
function declaration. Not so in the given case.


Yes so in the given case. The argument is of type "function that takes
no arguments and returns 'Bar'". You need to stop arguing and read the
archives and learn the C++ grammar.
The only problem is that Bar() returns a temporary, which can't bind to a
non-const reference. But that should produce a compile error. Steve
says it doesn't work, but he doesn't say what *does* happen. Once I
correct the const-ness of the T& parameter, it compiles fine, and
produces the correct output ("class Bar") in both cases.


REALLY?? On what compiler?

VC++ 2003 (version 7), (with "languages extensions disabled", so that it
doesn't allow silly non-standard things like the non-const-ness of the
reference parameter).


Doesn't allow, eh? Throw it away and get yourself 7.1. You'll thank
me for this.
This:
---------------------------------------------
struct A {
template<class T> explicit A(T const& t);
int foo();
};

struct B {};

int main() {
A a(B());
return a.foo();
}
---------------------------------------------
does not compile. Now, you tell me why.

V

It compiles fine. It fails to link, because neither the constructor nor the
function foo are defined. Once I add the bodies for those, it works fine.
What compiler does it fail on, and with what message?


It fails to compile on VC++ 7.1, VC++ v8.0 Beta, Comeau 4.3.3 Beta, g++
v2.96, g++ v3.2, g++ v3.2.2, MIPS Pro C++ v7.4, HP aCC B3910B A.03.50,
and I can go on. I don't have time for this, though.

V
Jul 23 '05 #10
mrstephengross wrote:
Interesting; I'll look it up... Is there a correct syntax for the kind
of instantiation I'm trying to invoke?


Probably

Command cmd2 = Command(Bar());

It involves a temporary, but it is allowed to be optimized away.

V
Jul 23 '05 #11

"Howard" <al*****@hotmail.com> wrote in message news:eQ********************@bgtnsc04-news.ops.worldnet.att.net...
[snip]
Command cmd(Bar());

couldn't be a function declaration.


Command cmd(Bar());
is identical
Command cmd(Bar (*pf)());

[snip]
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn


Jul 23 '05 #12

"Alex Vinokur" <al****@big-foot.com> skrev i en meddelelse
news:d9**********@domitilla.aioe.org...

"Howard" <al*****@hotmail.com> wrote in message
news:eQ********************@bgtnsc04-news.ops.worldnet.att.net...
[snip]
Command cmd(Bar());

couldn't be a function declaration.
Command cmd(Bar());
is identical
Command cmd(Bar (*pf)());

I believe it is identical to
Command cmd(Bar b);

/Peter
[snip]
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #13

"Peter Koch Larsen" <pk*****@mailme.dk> wrote in message news:vI********************@news000.worldonline.dk ...

"Alex Vinokur" <al****@big-foot.com> skrev i en meddelelse
news:d9**********@domitilla.aioe.org...


[snip]
Command cmd(Bar());
is identical
Command cmd(Bar (*pf)());

I believe it is identical to
Command cmd(Bar b);


See http://www.parashift.com/c++-faq-lit...html#faq-10.19

----- Function-1 declaration -----
Command cmd(Bar());
Command cmd(Bar (*pf)());

Here a function called 'cmd' is declared that
* returns a 'Command'
and
* takes as a single parameter of type "non-member function that i)returns a 'Bar' and ii)takes no arguments".

----- Function-2 declaration -----
Command cmd(Bar);
Command cmd(Bar b);

Here a function called 'cmd' is declared that
* returns a 'Command'
and
* takes as a single parameter of type 'Bar'

[snip]
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #14

"Alex Vinokur" <al****@big-foot.com> skrev i en meddelelse
news:d9**********@domitilla.aioe.org...

"Peter Koch Larsen" <pk*****@mailme.dk> wrote in message
news:vI********************@news000.worldonline.dk ...

"Alex Vinokur" <al****@big-foot.com> skrev i en meddelelse
news:d9**********@domitilla.aioe.org...
[snip]
> Command cmd(Bar());
> is identical
> Command cmd(Bar (*pf)());

I believe it is identical to
Command cmd(Bar b);


See http://www.parashift.com/c++-faq-lit...html#faq-10.19


I just did. I'm not sure that part is correct.

----- Function-1 declaration -----
Command cmd(Bar());
Command cmd(Bar (*pf)());

Here a function called 'cmd' is declared that
* returns a 'Command'
and
* takes as a single parameter of type "non-member function that i)returns
a 'Bar' and ii)takes no arguments".
How can you make Bar look like a function?? I do not believe that is
correct.

Try:
typedef int (*pf)(int);
int what_is_this(int());
pf f = what_is_this;

This compiles in Microsoft VC 7.1 and i believe the compiler is correct
here.
int what_is_this(int());
is the same declaration as

int what_is_this(int );

----- Function-2 declaration -----
Command cmd(Bar);
Command cmd(Bar b);

Here a function called 'cmd' is declared that
* returns a 'Command'
and
* takes as a single parameter of type 'Bar'

[snip]
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #15
Peter Koch Larsen wrote:
"Alex Vinokur" <al****@big-foot.com> skrev i en meddelelse
news:d9**********@domitilla.aioe.org...

"Peter Koch Larsen" <pk*****@mailme.dk> wrote in message
news:vI********************@news000.worldonline.dk ...

"Alex Vinokur" <al****@big-foot.com> skrev i en meddelelse
news:d9**********@domitilla.aioe.org...


[snip]
Command cmd(Bar());
is identical
Command cmd(Bar (*pf)());
I believe it is identical to
Command cmd(Bar b);


See http://www.parashift.com/c++-faq-lit...html#faq-10.19


I just did. I'm not sure that part is correct.

----- Function-1 declaration -----
Command cmd(Bar());
Command cmd(Bar (*pf)());

Here a function called 'cmd' is declared that
* returns a 'Command'
and
* takes as a single parameter of type "non-member function that
i)returns a 'Bar' and ii)takes no arguments".


How can you make Bar look like a function?? I do not believe that is
correct.

Try:
typedef int (*pf)(int);
int what_is_this(int());
pf f = what_is_this;

This compiles in Microsoft VC 7.1 and i believe the compiler is
correct here.
int what_is_this(int());
is the same declaration as

int what_is_this(int );


No. Try

#include <iostream>
#include <typeinfo>

int main() {
int what_is_this(int());
std::cout << typeid(what_is_this).name() << std::endl;
}

Now, discard the '__cdecl' nonsense, and read the declaration.

V
Jul 23 '05 #16
Peter Koch Larsen wrote:
[snip]
Try:
typedef int (*pf)(int);
int what_is_this(int());
pf f = what_is_this;

This compiles in Microsoft VC 7.1 and i believe the compiler is correct
here.
int what_is_this(int());
is the same declaration as

int what_is_this(int );

[snip]

I tried to compile following program:
--- xxx3.cpp ---
typedef int (*pf)(int);
int what_is_this(int()) {}
int main()
{
pf f = what_is_this;
return 0;
}
----------------

g++ 3.4.1:
xxx3.cpp: In function `int main()':
xxx3.cpp:5: error: invalid conversion from `int (*)(int (*)())' to
`int(*)(int)'
Digital Mars C++ 8.38n:
xxx3.cpp(5) : Error: need explicit cast to convert
from: int (*C func)(int (*C func)())
to : int (*C func)(int )
Borland C++ 5.5.1:
Error E2034 xxx3.cpp 5: Cannot convert 'int (*)(int (*)())' to 'int
(*)(int)' in function main()
Microsoft C++ 13.00.9466:
xxx3.cpp(2) : error C2448: 'what_is_this' : function-style initializer
appears to be a function definition
xxx3.cpp(5) : error C2065: 'what_is_this' : undeclared identifier
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #17
Try:
typedef int (*pf)(int);
int what_is_this(int());
pf f = what_is_this;

This compiles in Microsoft VC 7.1 and i believe the compiler is correct
here.
int what_is_this(int());
is the same declaration as

int what_is_this(int );


MSVC 7.1 (13.10.3077) does _NOT_ compile this:

int main(int , const char **)
{
typedef int (*pf)(int);
int what_is_this(int());
pf f = what_is_this;

return 0;
}

output:

error C2440: 'initializing' : cannot convert from
'int (*)(int (*)(void))' to 'pf'

With or without language extensions - the error is the same.
So what are you talking about?
Jul 23 '05 #18

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

Similar topics

4
by: Sebastian Faust | last post by:
Hi, I have 4 questions related to templates. I wanna do something like the following: template<typename T> class Template { public: Template_Test<T>()
3
by: Gianni Mariani | last post by:
I was a little surprised by this: It seems like the code below should not compile but the Comeau 4.3.3 compiler accepts it and the gcc 3.4(prerel) compiler rejects it and MSVC++7.1 ICE's. ...
7
by: Bo Peng | last post by:
Dear List, I have a class that may or may not have several features. For example, there might be "partition" to d_data of obj. The code is like (please ignore grammar mistakes): ...
3
by: Gandu | last post by:
Could some C++ guru please help me. I have a template based general linked list class that I want to inherit publicly to create a queue class. In the case of non-template inheritance, I can use:...
2
by: max_sang | last post by:
Hello I have a nasty problem... take a look at this code: struct Parser { Parser(const string& s) { ... tokenizes s into pieces... } template <class T> to(size_t idx); private: vector<string>...
14
by: Bart Samwel | last post by:
Hi everybody, I would really like some help explaining this apparent discrepancy, because I really don't get it. Here is the snippet: void foo(int&); void foo(int const&); ...
10
by: ma740988 | last post by:
Part of my confusion here is certainly my ignorance of templates and std::auto_ptr. Two topics, I've perused but need to really _delve_ into. In any event, consider the 'test' source. #...
3
by: Sven Groot | last post by:
This was posted by someone in comp.lang.c++, and later in microsoft.public.vstudio.general, but since I know Carl is in this group, and he's the one that should read this, I've reposted it here....
12
by: aaragon | last post by:
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...
3
by: Fred Kleinschmidt | last post by:
I have a template:: template <class Vclass Vct { public: Vct(V); }; template <class V> Vct<V>::Vct( V vin ) { /*...*/
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.