Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Defining Non-Member Functions for Template Member Types

Reply
Thread Tools

Defining Non-Member Functions for Template Member Types

 
 
flounder
Guest
Posts: n/a
 
      04-01-2009
The compiler is unable to find a match for the call to munge() and
operator==() in is_equal() below. Can someone post an explanation and/
or suggest a workaround?

Thanks!

template<class T>
struct Foo {
struct Bar {};
};

template<class T>
bool operator==(const typename Foo<T>::Bar&, const typename
Foo<T>::Bar&);

template<class T>
void munge(typename Foo<T>::Bar* );

inline bool
is_equal(Foo<int>::Bar x, Foo<int>::Bar y)
{
munge(&x);
return x == y; // no operator "==" matches these operands
}
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-01-2009
* flounder:
> The compiler is unable to find a match for the call to munge() and
> operator==() in is_equal() below. Can someone post an explanation and/
> or suggest a workaround?
>
> Thanks!
>
> template<class T>
> struct Foo {
> struct Bar {};
> };
>
> template<class T>
> bool operator==(const typename Foo<T>::Bar&, const typename
> Foo<T>::Bar&);
>
> template<class T>
> void munge(typename Foo<T>::Bar* );
>
> inline bool
> is_equal(Foo<int>::Bar x, Foo<int>::Bar y)
> {
> munge(&x);
> return x == y; // no operator "==" matches these operands
> }


I googled.

See <url: http://www.codeguru.com/forum/archive/index.php/t-395268.html>;
"non-deduced context".

However while it seems the facts there are OK, the rationalization there seems
very fishy to me. Perhaps that rationalization is the standard's rationale (I'm
too lazy to check). But in a context like above I see no good reason why the
language could not have permitted the matching: there can be only one match.

I can see a bad reason, though, namely treating all types the same way, and the
above would indeed be problematic with Bar a typedef'ed name, e.g. for 'int'.

But the reason we use types and scopes (argh, declarative regions[1], now that
the C++ standardization has redefined our terminology) and so on is exactly to
discriminate between different things, even things that are technically the same
but just conceptually different, and I think the language should support that.

If the language had supported it then I think one would have had to write e.g.

template< typename T >
void munge( struct Foo<T>::Bar* );

But since the language doesn't support it the issue is moot.

Cheers & hth.,

- Alf


Notes:
[1] Or whatever the proper C++ term is!

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      04-01-2009
On Apr 1, 3:52 am, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * flounder:
> > The compiler is unable to find a match for the call to
> > munge() and operator==() in is_equal() below. Can someone
> > post an explanation and/ or suggest a workaround?


> > template<class T>
> > struct Foo {
> > struct Bar {};
> > };


> > template<class T>
> > bool operator==(const typename Foo<T>::Bar&, const typename
> > Foo<T>::Bar&);


> > template<class T>
> > void munge(typename Foo<T>::Bar* );


> > inline bool
> > is_equal(Foo<int>::Bar x, Foo<int>::Bar y)
> > {
> > munge(&x);
> > return x == y; // no operator "==" matches these operands
> > }


> I googled.


> See
> <url:http://www.codeguru.com/forum/archive/index.php/t-395268.html>;
> "non-deduced context".


> However while it seems the facts there are OK, the
> rationalization there seems very fishy to me. Perhaps that
> rationalization is the standard's rationale (I'm too lazy to
> check). But in a context like above I see no good reason why
> the language could not have permitted the matching: there can
> be only one match.


The problem is that in the general case, at least, the compiler
would have to verify all of the possible expansions of Foo<>.
Suppose, for example, one of them expanded to contain:
typedef typename Foo<int>::Bar Bar ;
.. (That would make the call ambiguous.) It's easy for a human,
looking at the template definition, and knowing that there are
no explicit specializations, to realize that this could not be
the case, but this realization is based on a higher degree of
logic than compilers are capable of.

> I can see a bad reason, though, namely treating all types the
> same way, and the above would indeed be problematic with Bar a
> typedef'ed name, e.g. for 'int'.


Exactly. And you don't know what Bar will be in Foo<T> until
you've instantiated Foo<T>.

The problem is that we humans (most of us, anyway) can think
very well in abstract terms, along the lines of "for all T...".
Machines can't, or at least, current compilers don't incorporate
any technology that can.

--
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
 
Martin Eisenberg
Guest
Posts: n/a
 
      04-01-2009
flounder wrote:

> The compiler is unable to find a match for the call to munge()
> and operator==() in is_equal() below. Can someone post an
> explanation and/ or suggest a workaround?


Regarding operators, you might (ab)use definitions in friend
declarations:

template<class T>
struct Foo {
struct Bar {
friend bool operator==(const Bar&, const Bar&)
{ return true; }
};
};

This puts one non-template free operator==() per Foo<T> instance in
Foo's enclosing namespace. Regarding functions that aren't known at
the time of declaration of Bar or shouldn't always be declared along
with it, I suppose the next best thing is to make them fully generic
and then constrain with Boost's Concept Check or enable_if. However,
enable_if still won't let you derive type T (or Foo<T>) in such a
function.


Martin

--
Quidquid latine scriptum est, altum videtur.
 
Reply With Quote
 
flounder
Guest
Posts: n/a
 
      04-01-2009
On Mar 31, 8:52*pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * flounder:
>
>
>
>
>
> > The compiler is unable to find a match for the call to munge() and
> > operator==() in is_equal() below. *Can someone post an explanation and/
> > or suggest a workaround?

>
> > Thanks!

>
> > template<class T>
> > struct Foo {
> > * * struct Bar {};
> > };

>
> > template<class T>
> > bool operator==(const typename Foo<T>::Bar&, *const typename
> > Foo<T>::Bar&);

>
> > template<class T>
> > void munge(typename Foo<T>::Bar* );

>
> > inline bool
> > is_equal(Foo<int>::Bar x, Foo<int>::Bar y)
> > {
> > * * munge(&x);
> > * * return x == y; * *// no operator "==" matches these operands
> > }

>
> I googled.
>
> See <url:http://www.codeguru.com/forum/archive/index.php/t-395268.html>;
> "non-deduced context".
>
> However while it seems the facts there are OK, the rationalization there seems
> very fishy to me. Perhaps that rationalization is the standard's rationale (I'm
> too lazy to check). But in a context like above I see no good reason why the
> language could not have permitted the matching: there can be only one match.
>
> I can see a bad reason, though, namely treating all types the same way, and the
> above would indeed be problematic with Bar a typedef'ed name, e.g. for 'int'.
>
> But the reason we use types and scopes (argh, declarative regions[1], now that
> the C++ standardization has redefined our terminology) and so on is exactly to
> discriminate between different things, even things that are technically the same
> but just conceptually different, and I think the language should support that.
>
> If the language had supported it then I think one would have had to write e.g.
>
> * *template< typename T >
> * *void munge( struct Foo<T>::Bar* );
>
> But since the language doesn't support it the issue is moot.
>
> Cheers & hth.,
>
> - Alf
>
> Notes:
> [1] Or whatever the proper C++ term is!
>
> --
> Due to hosting requirements I need visits to <url:http://alfps.izfree.com/>.
> No ads, and there is some C++ stuff! Just going there is good. Linking
> to it is even better! Thanks in advance!- Hide quoted text -
>
> - Show quoted text -


Thanks to all for your replies. Alf, you're clearly a better Google'r
than I.
 
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
overloading non-template member functions with template member functions Hicham Mouline C++ 1 04-24-2009 07:47 AM
overloading non-template member functions with template member functions Hicham Mouline C++ 0 04-23-2009 11:42 AM
Template member functions in template class with separate definition =?iso-8859-1?q?Erik_Wikstr=F6m?= C++ 5 12-14-2006 01:04 PM
Template Member Functions of Template Classes gogo1969@gmail.com C++ 2 02-05-2006 03:29 AM
parse error in gcc but success in vc.net, call a non_template class's template member function from a template class's member function! ken C++ 2 06-28-2005 06:57 AM



Advertisments