Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template instantiation conflict with function definition

Reply
Thread Tools

Template instantiation conflict with function definition

 
 
Alessandro [AkiRoss] Re
Guest
Posts: n/a
 
      05-12-2009
Hello there!
While developing a policy-based application, I tried a code like this
one (which is real code).

I'm using g++ 4.3.3, which gives me these errors:
templ_error.cpp: In function ‘int main()’:
templ_error.cpp:22: error: multiple parameters named ‘base’
templ_error.cpp:23: error: request for member ‘exec’ in ‘test’, which
is of non-class type ‘Test<Numeric<3>, Numeric<5> > ()(Numeric<3>,
Numeric<5>)’

But I can't understand where is the problem: it seems that g++ read my
declaration of a variable as a function definition. Please tell me if
I'm doing it wrong: I can't see the error.
Here's the code of templ_error.cpp

#include <iostream>

using namespace std;

template <typename A, typename B>
struct Test {
A a;
B b;
Test(A a_, B b_): a(a_), b(b_) {}
void exec() { cout << "Executed!" << a() << "-" << b() <<"\n"; }
};

template <int X>
struct Numeric {
int base;
Numeric(int base_): base(base_) {}
int operator()() { return base + X; }
};

int main() {
int base = 1;
Test<Numeric<3>, Numeric<5> > test(Numeric<3>(base), Numeric<5>
(base));
test.exec();
return 0;
}


ps. Also with g++ 4.1 gives errors: the only difference is that
"multiple parameters name" is not present as it has introduced in gcc
4.3.

Any help is appreciated
Thanks!

Regards
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      05-13-2009
Alessandro [AkiRoss] Re wrote:
> Hello there!
> While developing a policy-based application, I tried a code like this
> one (which is real code).
>
> I'm using g++ 4.3.3, which gives me these errors:
> templ_error.cpp: In function ‘int main()’:
> templ_error.cpp:22: error: multiple parameters named ‘base’
> templ_error.cpp:23: error: request for member ‘exec’ in ‘test’, which
> is of non-class type ‘Test<Numeric<3>, Numeric<5> > ()(Numeric<3>,
> Numeric<5>)’
>
> But I can't understand where is the problem: it seems that g++ read my
> declaration of a variable as a function definition. Please tell me if
> I'm doing it wrong: I can't see the error.
> Here's the code of templ_error.cpp
>
> #include <iostream>
>
> using namespace std;
>
> template <typename A, typename B>
> struct Test {
> A a;
> B b;
> Test(A a_, B b_): a(a_), b(b_) {}
> void exec() { cout << "Executed!" << a() << "-" << b() <<"\n"; }
> };
>
> template <int X>
> struct Numeric {
> int base;
> Numeric(int base_): base(base_) {}
> int operator()() { return base + X; }
> };
>
> int main() {
> int base = 1;
> Test<Numeric<3>, Numeric<5> > test(Numeric<3>(base), Numeric<5>
> (base));


The line above declares a function 'test' with two arguments, 'base' and
'base'. The first argument is of type 'Numeric<3>', the second is of
type 'Numeric<5>'. If you needed to construct an object 'test' of type
'Test<...>', then you need to move your parentheses a bit:

Test<Numeric<3>, Numeric<5> >
test( ( Numeric<3> ) base, ( Numeric<5> )base );

Notice that I put the types in parentheses making those C-style type
cast expressions.

> test.exec();


This line in your original program tries to apply '.' to the function
type, and that's what the second error message is about. Pay attention
to what your compiler is telling you!

> return 0;
> }
>
>
> ps. Also with g++ 4.1 gives errors: the only difference is that
> "multiple parameters name" is not present as it has introduced in gcc
> 4.3.


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      05-13-2009
On May 13, 1:53 am, "Alessandro [AkiRoss] Re" <(E-Mail Removed)>
wrote:

> While developing a policy-based application, I tried a code
> like this one (which is real code).


> I'm using g++ 4.3.3, which gives me these errors:
> templ_error.cpp: In function ‘int main()’:
> templ_error.cpp:22: error: multiple parameters named ‘base’
> templ_error.cpp:23: error: request for member ‘exec’ in ‘test’, which
> is of non-class type ‘Test<Numeric<3>, Numeric<5> > ()(Numeric<3>,
> Numeric<5>)’


> But I can't understand where is the problem: it seems that g++
> read my declaration of a variable as a function definition.


That's because it is a function declaration.

[...]
> int main() {
> int base = 1;
> Test<Numeric<3>, Numeric<5> > test(Numeric<3>(base), Numeric<5> (base));


This declares (not defines) a function taking a Numeric< 3 > and
a Numeric< 5 > as arguments, and returning a Test< Numeric< 3 >,
Numeric< 5 > >. If what you want is a variable of type Test<
Numeric< 3 >, Numeric< 5 > >, initialized with a Numeric< 3 >
and a Numeric< 5 >, you must do something to prevent the string
"Numeric< 3 >( base )" (and "Numeric< 5 >( base )") from being
taken as a declaration:

Test< Numeric< 3 >, Numeric< 5 > >
test( (Numeric< 3 >( base )),
(Numeric< 5 >( base )) ) ;

Note the extra parentheses: C++ syntax doesn't allow the
declaration of a function parameter to be in parentheses, so the
results can only be an expression.

The fundamental problem is that "Numeric< 3 >( base )" can be
parsed as either an expression or a declaration. In such cases,
the rules of the language say that if a declaration is legal, it
is parsed as a declaration. So you have to do something to
create a context where a declaration would not be legal. My
favorite solution is the above, because it is (I think) the most
universally applicable. Other solutions would be to put the
parentheses around the Numeric< 3 > (only works if there is
exactly one argument), or to use copy initialization (doesn't
work if the type being constructed doesn't support copy).

This is sometimes known as C++'s most embarassing parse.
Everyone gets caught out by it from time to time.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      05-13-2009
On 13 mai, 10:04, James Kanze <(E-Mail Removed)> wrote:
> On May 13, 1:53 am, "Alessandro [AkiRoss] Re" <(E-Mail Removed)>
> wrote:
>
> > While developing a policy-based application, I tried a code
> > like this one (which is real code).
> > I'm using g++ 4.3.3, which gives me these errors:
> > templ_error.cpp: In function ‘int main()’:
> > templ_error.cpp:22: error: multiple parameters named ‘base’
> > templ_error.cpp:23: error: request for member ‘exec’ in ‘test’, which
> > is of non-class type ‘Test<Numeric<3>, Numeric<5> > ()(Numeric<3>,
> > Numeric<5>)’
> > But I can't understand where is the problem: it seems that g++
> > read my declaration of a variable as a function definition.

>
> That's because it is a function declaration.
>
> * * [...]
>
> > int main() {
> > * * int base = 1;
> > * * Test<Numeric<3>, Numeric<5> > test(Numeric<3>(base), Numeric<5> (base));

>
> This declares (not defines) a function taking a Numeric< 3 > and
> a Numeric< 5 > as arguments, and returning a Test< Numeric< 3 >,
> Numeric< 5 > >. *

[snip]
> Note the extra parentheses: C++ syntax doesn't allow the
> declaration of a function parameter to be in parentheses, so the
> results can only be an expression.
>
> The fundamental problem is that "Numeric< 3 >( base )" can be
> parsed as either an expression or a declaration. *In such cases,
> the rules of the language say that if a declaration is legal, it
> is parsed as a declaration. *So you have to do something to
> create a context where a declaration would not be legal.

[snip]
> This is sometimes known as C++'s most embarrassing parse.
> Everyone gets caught out by it from time to time.


And I thought it was the necessary space in nested template
list<vector<int>> -> list<vector<int> >

--
Michael
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
conflict function definition with stdlib.h hqin C Programming 24 01-17-2011 05:28 AM
Explicit instantiation of STL vector demands explicit instantiation of all the templates it using internally. krunalbauskar@gmail.com C++ 1 12-25-2006 03:51 PM
point of definition or instantiation of a template ES Kim C++ 4 04-15-2005 01:48 AM
Explicit template instantiation from template function doesn't compile? Fernando Cuenca C++ 4 09-06-2004 04:06 PM
Can a successfully compileable template definition fail on instantiation? David C++ 2 05-13-2004 11:59 AM



Advertisments