By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,513 Members | 1,815 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,513 IT Pros & Developers. It's quick & easy.

What is wrong with the following program (using an empty class to choose overloaded function)?

P: n/a
Hi,

I run into error with the following program. Would you please help me?

Best wishes,
Peng

struct tag1{};
struct tag2{};

template <typename T>
inline void test(tag1){
}

template <typename T>
inline void test(tag2){
}

int main(){
test(tag1);//error with g++-3.4.4
}

Nov 2 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Pe*******@gmail.com wrote:
Hi,

I run into error with the following program. Would you please help me?

Best wishes,
Peng

struct tag1{};
struct tag2{};

template <typename T>
inline void test(tag1){
}

template <typename T>
inline void test(tag2){
}

int main(){
test(tag1);//error with g++-3.4.4
tag1 is not a variable, it is a type. I would guess that you're getting
a redeclaration error. }

Nov 2 '05 #2

P: n/a

<Pe*******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Hi,

I run into error with the following program. Would you please help me?

Best wishes,
Peng

struct tag1{};
struct tag2{};

template <typename T>
inline void test(tag1){
}

template <typename T>
inline void test(tag2){
}

int main(){
test(tag1);//error with g++-3.4.4


The argument must be an instance of an object,
not the name of a type. In addition, since
'test' is a function template, and there's
no way to deduce one, a template argument must
be specified.

Try:

test<int>(tag1());

BTW I think you're obscuring things with your templates.
They're not needed at all.

struct tag1{};
struct tag2{};

void test(tag1){
}

void test(tag2){
}

int main(){
test(tag1());
return 0;
}

I think you need to read more about templates and what
they're for.

-Mike
Nov 2 '05 #3

P: n/a

<Pe*******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
| Hi,
|
| I run into error with the following program. Would you please help me?
|
| Best wishes,
| Peng
|
| struct tag1{};
| struct tag2{};

should be:

struct Tag1{};
struct Tag2{};

By convention and to save a programmer from having to pop aspirin for a
living, a capitalized name is reserved for structs and classes. So if
you see Tag1, its a type, while tag1 might be an instance of a Tag1
type.

|
| template <typename T>
| inline void test(tag1){
| }

tag1 here is a type, not an instance... you don't need multiple
definitions of the same template either. The following template can
potentially accept any class.

template< typename T >
void test( T& t ) // pass_by_reference
{
}

or

template< typename T >
void test( const T& t ) // pass_by_const_reference
{
// t is unmodifiable and therefore safe
}
|
| template <typename T>
| inline void test(tag2){
| }
above not needed...

|
| int main(){
| test(tag1);//error with g++-3.4.4
// error because tag1 was a type and test() doesn't exist.

Tag1 tag1; // tag1 is an instance of a Tag1 type.
Tag2 tag2;

test< Tag1 >(tag1); // templated<> with a Tag1 type,
// and tag1 is the object being passed
test< Tag2 >(tag2);

int n;
test< int >(n); // doing it with a primitive integer, and so on...

| }
|

If you really did mean to specialize the test template...then...

template< typename T = Tag1 >
void test( T& t )
{
// do this if T is Tag1
}

template<>
void test<Tag2>( T& t )
{
// do this if T is Tag2
}

int main()
{
Tag1 tag1;
test(tag1); // default T = Tag1

Tag2 tag2;
test<Tag2>(tag2); // you must tell the compiler
}

Nov 2 '05 #4

P: n/a

Peter_Julian wrote:
<Pe*******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
| Hi,
|
| I run into error with the following program. Would you please help me?
|
| Best wishes,
| Peng
| ....
If you really did mean to specialize the test template...then...

template< typename T = Tag1 >
void test( T& t )
{
// do this if T is Tag1
}
Only a class template can specify a default type parameter. A function
template may not.
template<>
void test<Tag2>( T& t )
{
// do this if T is Tag2
}
Since the only purpose of the function's parameter is to select the
specialization, I think test() should be specialized for Tag2 like so:

template <>
void test( Tag2 t)
{
}

Tag2 is an empty class - so there is no reason either to pass the
parameter by reference or to declare it const.
int main()
{
Tag1 tag1;
test(tag1); // default T = Tag1
No, there is no default type possible here.
Tag2 tag2;
test<Tag2>(tag2); // you must tell the compiler
}


If the test function template deduced the specialized type from its
parameter as I suggested above, then calling test( tag2) would be
possible.

Greg

Nov 2 '05 #5

P: n/a
> The argument must be an instance of an object,
not the name of a type.
Yes, true - arg must be an instance of type.
In addition, since
'test' is a function template, and there's
no way to deduce one, a template argument must
be specified.
Hmmm, ever heard of make functions - function templates determine
(deduce) the template parameters from the arguments passed (C++
template p.12). For his example this may be true. How do you think
std::min, std::max, std::make_pair can be called without explicitly
specifying the template parameters :0.

Try:

test<int>(tag1());
.... or
test( tag1() ); //Should work to, and
//instantiate test<tag1>, which is what he wanted.

BTW I think you're obscuring things with your templates.
They're not needed at all.
Maybe true, but trying things out to come to grips is not so bad.

I think you need to read more about templates and what
they're for.
IMHO you may require some touching up too.

-Mike


Werner

Nov 2 '05 #6

P: n/a

Mike Wahler wrote:
<Pe*******@gmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Hi,

I run into error with the following program. Would you please help me?

Best wishes,
Peng

struct tag1{};
struct tag2{};

template <typename T>
inline void test(tag1){
}

template <typename T>
inline void test(tag2){
}

int main(){
test(tag1);//error with g++-3.4.4
The argument must be an instance of an object,
not the name of a type. In addition, since
'test' is a function template, and there's
no way to deduce one, a template argument must
be specified.


Please ignore my previous msg, I read the original posting too quick. I
took it for:

template <typename T>
inline void test( T )
{
}

struct Tag1{};
struct Tag2{};

int main()
{
test( Tag1() );
test( Tag2() );
//..or test( 10 );
}

because this would be the more obvious thing. In this case one would
not require test<int>( Tag1() ); //And of course it would not compile

Try:

test<int>(tag1());
Yes, absolutely.

BTW I think you're obscuring things with your templates.
They're not needed at all.
Certainly, but he may be learning (fooling around to learn).
I think you need to read more about templates and what
they're for.
He certainly does, and you don't (as I mentioned previously).

-Mike


Regards (and sorry),

Werner

Nov 2 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.