![]() |
|
|
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. |
|
|||||||
![]() |
|
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
![]() |
|
| Thread Tools | Search this Thread |
| Display Modes | |
|
|