Welcome to the { mindfrost82.com } forums.

You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today!

If you have any problems with the registration process or your account login, please contact contact us.

Go Back   { mindfrost82.com } > Gadget Corner > Tech Newsgroups > Programming > C++

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 08-05-2008, 06:11 AM
chris42f@gmail.com
 
Posts: n/a
Templates and greater than / less than ambiguity

Hi all,

I've got a problem which appears to be related to the ambiguity
between
template <> brackets and greater and less than symbols... Here's a
snippet of
code which I'm having trouble with:

--------------------------------------------------
struct Tag
{
typedef int type;
};

struct A
{
template<typename TagT>
typename TagT::type find(typename TagT::type i)
{
return i;
}
};

template<typename T>
int foo()
{
int i = 0;
T t;
// The following doesn't compile but is well-formed if t.find is a
template
// member of T, and Tag is a type.
i = t.find<Tag>(1);
// While the below should be functionally equivalent
//i = static_cast<A>(t).find<Tag>(42);

return i;
}

int main()
{
int i = foo<A>();
return 0;
}

--------------------------------------------------

This is just a cut-down toy version, but it shows the main thing I'm
having
problems with. What I want is to be able to use an expression like

t.find<Tag>(1);

where t is a template type, Tag is some tag struct, and find is a
template
member function. When I try to compile the above example, g++ gives
an error
like

main.cpp: In function 'int foo()':
main.cpp:22: error: expected primary-expression before '>' token

The error goes away if I write an explicit cast:

static_cast<A>(t).find<Tag>(1);

I can see how the expression could be ambiguous, since the following
compiles
fine:

--------------------------------------------------
struct B
{
static const int find = 1;
};

int bar()
{
B b;
int Tag = 1;
int j = b.find < Tag > (1);
return j;
}
--------------------------------------------------

- in this case Tag and b.find are variables, but the exact same syntax
is
used.

Am I doing something wrong here? Is this somehow forbidden by the C++
spec?
Otherwise I guess it's a compiler error...

Any help appreciated, thanks for your time.
~Chris F.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #2 (permalink)  
Old 08-05-2008, 05:27 PM
Pavel Minaev
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

On Aug 5, 9:11 am, chris...@gmail.com wrote:
> I've got a problem which appears to be related to the ambiguity
> between
> template <> brackets and greater and less than symbols... Here's a
> snippet of
> code which I'm having trouble with:
>
> --------------------------------------------------
> struct Tag
> {
> typedef int type;
>
> };
>
> struct A
> {
> template<typename TagT>
> typename TagT::type find(typename TagT::type i)
> {
> return i;
> }
>
> };
>
> template<typename T>
> int foo()
> {
> int i = 0;
> T t;
> // The following doesn't compile but is well-formed if t.find is a
> template
> // member of T, and Tag is a type.
> i = t.find<Tag>(1);


As you've correctly spotted, it is ambiguous because the compiler
cannot tell in advance what T::find will be - a template, or something
with operator<.
You should use the following syntax to explicitly tell the compiler
that T::find is a function template:

i = t.template find<Tag>(1);


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #3 (permalink)  
Old 08-05-2008, 05:30 PM
Jiang
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

On Aug 5, 2:11 pm, chris...@gmail.com wrote:

[...]

> where t is a template type, Tag is some tag struct, and find is a
> template
> member function. When I try to compile the above example, g++ gives
> an error
> like
>
> main.cpp: In function 'int foo()':
> main.cpp:22: error: expected primary-expression before '>' token
>
> The error goes away if I write an explicit cast:
>
> static_cast<A>(t).find<Tag>(1);
>


The above code is ill-formed. It should be

i = t.template find<Tag>(1);

Add template keyword to tell the compiler here you are doing
template programming. Otherwise the compiler will treat "<"
as "less than" :

In 14.2/p4, we have

When the name of a member template specialization
appears after . or -> in a postfix-expression, or after
nested-name-specifier in a qualified-id, and the
postfix-expression or qualified-id explicitly depends on a
template-parameter (14.6.2), the member template name
must be prefixed by the keyword template.
Otherwise the name is assumed to name a non-template.

HTH

Jiang


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #4 (permalink)  
Old 08-05-2008, 05:30 PM
Alberto Ganesh Barbati
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

chris42f@gmail.com ha scritto:
> template<typename T>
> int foo()
> {
> int i = 0;
> T t;
> // The following doesn't compile but is well-formed if t.find is a
> template
> // member of T, and Tag is a type.
> i = t.find<Tag>(1);


This is a FAQ.

The code is *not* well-formed, because "find" is *not* interpreted as
the name of a template. You must write:

i = t.template find<Tag>(1);

This is because the syntactic disambiguation must happen at the point of
declaration of the template, where the type T is still unknown. It
cannot be deferred to point of instantiation, where T is substituted
with the actual type that happens to have a member template named "find".

HTH,

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #5 (permalink)  
Old 08-05-2008, 06:07 PM
Thomas Maeder
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

chris42f@gmail.com writes:

> --------------------------------------------------
> struct Tag
> {
> typedef int type;
> };
>
> struct A
> {
> template<typename TagT>
> typename TagT::type find(typename TagT::type i)
> {
> return i;
> }
> };
>
> template<typename T>
> int foo()
> {
> int i = 0;
> T t;
> // The following doesn't compile but is well-formed if t.find is a
> template


It's only well-formed if t.find is a template and if you explicitly
tell the compiler about it.


> // member of T, and Tag is a type.
> i = t.find<Tag>(1);


i = t.template find<Tag>(1);

Otherwise, the compiler has to assume that "find" does not name a
template.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #6 (permalink)  
Old 08-05-2008, 06:28 PM
Mathias Gaunard
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

On 5 août, 07:11, chris...@gmail.com wrote:

> template<typename T>
> int foo()
> {
> int i = 0;
> T t;
> // The following doesn't compile but is well-formed if t.find is a
> template
> // member of T, and Tag is a type.
> i = t.find<Tag>(1);


i = t.template find<Tag>(1);

Just like you need to use the keyword "typename" to say a static
member of a template-dependent type is a typename and not a static
variable, you need to use "template" to say a member function of a
template-dependent object is a template member function and not a
regular member function.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #7 (permalink)  
Old 08-05-2008, 06:28 PM
Markus Moll
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

Hi

chris42f@gmail.com wrote:
> What I want is to be able to use an expression like
>
> t.find<Tag>(1);
>
> where t is a template type, Tag is some tag struct, and find is a
> template member function. When I try to compile the above example, g++
> gives an error like
>
> main.cpp: In function 'int foo()':
> main.cpp:22: error: expected primary-expression before '>' token


[...]

> Am I doing something wrong here?


Yes.

> Is this somehow forbidden by the C++ spec?


Well, not exactly. The problem is that the compiler does not know that
t.find names a template, as it doesn't know what type t has. Just like with
typename, you have to tell the compiler that t.find is not an object, but
the name of a template:

t.template find<Tag>(1);

Markus


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #8 (permalink)  
Old 08-06-2008, 03:21 PM
chris42f@gmail.com
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

On Aug 6, 2:30 am, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
> chris...@gmail.com ha scritto:
>
> > template<typename T>
> > int foo()
> > {
> > int i = 0;
> > T t;
> > // The following doesn't compile but is well-formed if
> > // t.find is a template member of T, and Tag is a type.
> > i = t.find<Tag>(1);

>
> This is a FAQ.


Ah, indeed :-( For anyone reading this thread in the future,
further details may be found in question 6 of the C++ template
FAQ, "Why do I need to add "template" and "typename" in the
bodies of template definitions?":

http://womble.decadentplace.org.uk/c...plate-faq.html

I find the example given in faq 6 a little opaque, but
nevertheless it is there. Usage of the typename keyword for
disabiguation is covered in the C++ FAQ lite, but I couldn't
find a mention of this use of the template keyword there.

> The code is *not* well-formed, because "find" is *not*
> interpreted as the name of a template.


Oops, as others have also pointed out (thanks), my original code
is not well-formed. The comment was intended as an off-hand
remark "should be ok" rather than an actual claim of precise
well-formedness...

> You must write:
>
> i = t.template find<Tag>(1);
>
> This is because the syntactic disambiguation must happen at the
> point of declaration of the template, where the type T is still
> unknown. It cannot be deferred to point of instantiation, where
> T is substituted with the actual type that happens to have a
> member template named "find".


This makes sense, thanks.

Many thanks to all who replied, and apologies for the poor line
wrapping in my first message, I *hope* that is now fixed.
~Chris F.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #9 (permalink)  
Old 08-06-2008, 03:23 PM
chris42f@gmail.com
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

On Aug 6, 2:30 am, Jiang <goo.mai...@yahoo.com> wrote:
>
> Add template keyword to tell the compiler here you are doing
> template programming. Otherwise the compiler will treat "<"
> as "less than" :
>
> In 14.2/p4, we have
>
> When the name of a member template specialization
> appears after . or -> in a postfix-expression, or after
> nested-name-specifier in a qualified-id, and the
> postfix-expression or qualified-id explicitly depends on a
> template-parameter (14.6.2), the member template name
> must be prefixed by the keyword template.
> Otherwise the name is assumed to name a non-template.


Ok, so if I'm reading this standardese correctly:

In my case, find<Tag>
* is a member template specialization
* appears after . in a postfix expression

In addition,
* the postfix expression explicitly depends on a template
parameter, Tag.

Therefore, without including the keyword template, t.find is
assumed to be a non-template and the expression fails to parse.
This is because Tag is a type rather than a variable and doesn't
make sense in a less than comparison.

Thanks again,
~Chris F.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #10 (permalink)  
Old 08-07-2008, 04:58 PM
Yechezkel Mett
 
Posts: n/a
Re: Templates and greater than / less than ambiguity

On Aug 6, 5:23 pm, chris...@gmail.com wrote:
> On Aug 6, 2:30 am, Jiang <goo.mai...@yahoo.com> wrote:
> > In 14.2/p4, we have

>
> > When the name of a member template specialization
> > appears after . or -> in a postfix-expression, or after
> > nested-name-specifier in a qualified-id, and the
> > postfix-expression or qualified-id explicitly depends on a
> > template-parameter (14.6.2), the member template name
> > must be prefixed by the keyword template.
> > Otherwise the name is assumed to name a non-template.

>
> Ok, so if I'm reading this standardese correctly:
>
> In my case, find<Tag>
> * is a member template specialization
> * appears after . in a postfix expression
>
> In addition,
> * the postfix expression explicitly depends on a template
> parameter, Tag.


The postfix expression depends on the template parameter T, not Tag.

Yechezkel Mett


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
Reply

  { mindfrost82.com } > Gadget Corner > Tech Newsgroups > Programming > C++


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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

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



All times are GMT. The time now is 03:56 PM.


Powered by vBulletin, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.1.0 ©2007, Crawlability, Inc.
© 1999-2008 mindfrost82.com v11.0


Sponsors:
Loans | Advertising | Debt Consolidation | MPAA | Shares



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114