Connecting Tech Pros Worldwide Forums | Help | Site Map

Cannot invoke a templated ctor

Momchil Velikov
Guest
 
Posts: n/a
#1: Jul 19 '05
The following program produces error at the definition of ``b''. However it
compiles fine the second (supposedly equivalent) form of the templated
constructor. Why the two alternatives aren't equivalent ?

template<class Obj>
struct ptr_to_member
{
typedef void (Obj::* type) ();
};

struct A
{
A (void (*fn) ())
{
}

#if 1
template<class Obj>
A (typename ptr_to_member <Obj>::type fn)
{
}
#else
template<class Obj>
A (void (Obj::* fn) ())
{
}
#endif
};

void foo ()
{
}

struct bar
{
void baz ()
{
}
};

A a (foo);

A b (&bar::baz);

David B. Held
Guest
 
Posts: n/a
#2: Jul 19 '05

re: Cannot invoke a templated ctor


"Momchil Velikov" <velco@fadata.bg> wrote in message
news:87bded37.0309230014.7b71fb0c@posting.google.c om...[color=blue]
> [...]
> template<class Obj>
> A (typename ptr_to_member <Obj>::type fn)
> {
> }[/color]

This is a non-deducible context.
[color=blue]
> template<class Obj>
> A (void (Obj::* fn) ())
> {
> }[/color]

This context is deducible.

Basically, if the compiler has to instantiate a type to match a
template parameter, then the context is non-deducible (the
compiler is too lazy to do the instantiation, since it could
become arbitrarily complex, and probably lead to weird
recursions in some cases).

Dave


Chris Theis
Guest
 
Posts: n/a
#3: Jul 19 '05

re: Cannot invoke a templated ctor



"David B. Held" <dheld@codelogicconsulting.com> wrote in message
news:bkp4t7$a6l$1@news.astound.net...[color=blue]
> "Momchil Velikov" <velco@fadata.bg> wrote in message
> news:87bded37.0309230014.7b71fb0c@posting.google.c om...[color=green]
> > [...]
> > template<class Obj>
> > A (typename ptr_to_member <Obj>::type fn)
> > {
> > }[/color]
>
> This is a non-deducible context.
>[color=green]
> > template<class Obj>
> > A (void (Obj::* fn) ())
> > {
> > }[/color]
>
> This context is deducible.
>
> Basically, if the compiler has to instantiate a type to match a
> template parameter, then the context is non-deducible (the
> compiler is too lazy to do the instantiation, since it could
> become arbitrarily complex, and probably lead to weird
> recursions in some cases).
>
> Dave
>[/color]

[Just a comment]
Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very standard
compliant compiler in terms of templates, manages to deduce the context.

Chris


David B. Held
Guest
 
Posts: n/a
#4: Jul 19 '05

re: Cannot invoke a templated ctor


"Chris Theis" <Christian.Theis@nospam.cern.ch> wrote in message
news:bkpcn5$k21$1@sunnews.cern.ch...[color=blue]
> [...]
> [Just a comment]
> Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very
> standard compliant compiler in terms of templates, manages to
> deduce the context.[/color]

Interesting. Please try this code on it:

template <typename T>
struct identity
{
typedef T type;
};

template <typename T>
void foo(typename identity<T>::type)
{
}

int main()
{
int i;
foo(i);
}

Comeau online gives:

"ComeauTest.c", line 15: error: no instance of function template "foo"
matches the argument list
The argument types that you used are: (int)
foo(i);
^

Note that the identity metafunction is often used explicitly to
suppress deduction, so VC6 is truly broken indeed if it performs
the deduction anyway (but I have a suspicion that it doesn't,
and something else is going on with your test code).

Dave


Chris Theis
Guest
 
Posts: n/a
#5: Jul 19 '05

re: Cannot invoke a templated ctor



"David B. Held" <dheld@codelogicconsulting.com> wrote in message
news:bkpv7j$d9o$1@news.astound.net...[color=blue]
> "Chris Theis" <Christian.Theis@nospam.cern.ch> wrote in message
> news:bkpcn5$k21$1@sunnews.cern.ch...[color=green]
> > [...]
> > [Just a comment]
> > Interestingly enough Visual C++ 6.0 (SP5) which is not yet a very
> > standard compliant compiler in terms of templates, manages to
> > deduce the context.[/color]
>
> Interesting. Please try this code on it:
>
> template <typename T>
> struct identity
> {
> typedef T type;
> };
>
> template <typename T>
> void foo(typename identity<T>::type)
> {
> }
>
> int main()
> {
> int i;
> foo(i);
> }
>
> Comeau online gives:
>
> "ComeauTest.c", line 15: error: no instance of function template "foo"
> matches the argument list
> The argument types that you used are: (int)
> foo(i);
> ^[/color]

And IMHO it's right.
[color=blue]
>
> Note that the identity metafunction is often used explicitly to
> suppress deduction, so VC6 is truly broken indeed if it performs
> the deduction anyway (but I have a suspicion that it doesn't,
> and something else is going on with your test code).
>
> Dave
>[/color]

VC6 compiles the code just fine. Probably I'll give it a try on VC7
sometime.

Chris


Chris Theis
Guest
 
Posts: n/a
#6: Jul 19 '05

re: Cannot invoke a templated ctor



"David B. Held" <dheld@codelogicconsulting.com> wrote in message
news:bkp4t7$a6l$1@news.astound.net...[color=blue]
> "Momchil Velikov" <velco@fadata.bg> wrote in message
> news:87bded37.0309230014.7b71fb0c@posting.google.c om...[color=green]
> > [...]
> > template<class Obj>
> > A (typename ptr_to_member <Obj>::type fn)
> > {
> > }[/color]
>
> This is a non-deducible context.
>[color=green]
> > template<class Obj>
> > A (void (Obj::* fn) ())
> > {
> > }[/color]
>
> This context is deducible.
>
> Basically, if the compiler has to instantiate a type to match a
> template parameter, then the context is non-deducible (the
> compiler is too lazy to do the instantiation, since it could
> become arbitrarily complex, and probably lead to weird
> recursions in some cases).
>
> Dave
>[/color]

Hi Dave, can you give me the exact part of the standard for this, please.

Regards
Chris


Shane Beasley
Guest
 
Posts: n/a
#7: Jul 19 '05

re: Cannot invoke a templated ctor


"Chris Theis" <Christian.Theis@nospam.cern.ch> wrote in message news:<bkrgaa$r24$1@sunnews.cern.ch>...
[color=blue]
> VC6 compiles the code just fine. Probably I'll give it a try on VC7
> sometime.[/color]

FWIW, VC++.NET (aka VC++7) does not accept it. But since VC++6 accepts
it, I don't know why ISO C++ shouldn't also accept it. That is, I
figured it just happened to be difficult or impossible to do, but
VC++6 did it.

Sounds like a topic for comp.std.c++, actually.

- Shane
Jerry Coffin
Guest
 
Posts: n/a
#8: Jul 19 '05

re: Cannot invoke a templated ctor


In article <2f2d78e1.0309241538.304eaaa2@posting.google.com >,
sbeasley@cs.uic.edu says...

[ ... ]
[color=blue]
> FWIW, VC++.NET (aka VC++7) does not accept it. But since VC++6 accepts
> it, I don't know why ISO C++ shouldn't also accept it. That is, I
> figured it just happened to be difficult or impossible to do, but
> VC++6 did it.[/color]

Off the top of my head, I don't remember exactly what you're talking
about, but I guess it doesn't really matter. VC++ 6 simplifies the
language to the point that quite a few ambiguities in the real language
don't exist in its language. An ambiguity results when a particular
expression _could_ be interpreted in one of two possible ways. When/if
the compiler is simply limited to the point that it doesn't recognize
one of those possibilities at all, then what should be ambiguous input
is unambiguous for it. Making the compiler recognize the other
possibility, however, makes the expression ambiguous.

--
Later,
Jerry.

The universe is a figment of its own imagination.
David B. Held
Guest
 
Posts: n/a
#9: Jul 19 '05

re: Cannot invoke a templated ctor


"Chris Theis" <Christian.Theis@nospam.cern.ch> wrote in message
news:bksiil$k21$1@sunnews.cern.ch...[color=blue]
> [...]
> Hi Dave, can you give me the exact part of the standard for this,
> please.[/color]

I wish I could, by my only copy of the standard is on a dead HD,
so I'll have to give you the exact part of the draft standard instead:

14.8.2/9

14.8.2/10:

In a type which contains a nested-name-specifier, template
argument values cannot be deduced for template parameters
used within the nested-name-specifier. [Example:

template<int i, typename T>
T deduce(A<T>::X x, // T is not deduced here
T t, // but T is deduced here
B<i>::Y y); // i is not deduced here

I think paragraph 10 pretty much sums it up (it does for me,
anyway).

I also highly recommend the Vandevoorde/Josuttis text on
templates. It doesn't always make things clear, but it always
makes things precise, and since templates sometimes can't be
clear with any amount of explanation, precision is as good as
it gets. ;>

Dave


Momchil Velikov
Guest
 
Posts: n/a
#10: Jul 19 '05

re: Cannot invoke a templated ctor


"Chris Theis" <Christian.Theis@nospam.cern.ch> wrote in message news:<bksiil$k21$1@sunnews.cern.ch>...[color=blue]
> "David B. Held" <dheld@codelogicconsulting.com> wrote in message
> news:bkp4t7$a6l$1@news.astound.net...[color=green]
> > "Momchil Velikov" <velco@fadata.bg> wrote in message
> > news:87bded37.0309230014.7b71fb0c@posting.google.c om...[color=darkred]
> > > [...]
> > > template<class Obj>
> > > A (typename ptr_to_member <Obj>::type fn)
> > > {
> > > }[/color]
> >
> > This is a non-deducible context.
> >[color=darkred]
> > > template<class Obj>
> > > A (void (Obj::* fn) ())
> > > {
> > > }[/color]
> >
> > This context is deducible.
> >[/color]
> Hi Dave, can you give me the exact part of the standard for this, please.[/color]

14.8.2.4 [#4]

~velco
Shane Beasley
Guest
 
Posts: n/a
#11: Jul 19 '05

re: Cannot invoke a templated ctor


Jerry Coffin <jcoffin@taeus.com> wrote in message news:<MPG.19dbf842c1500f3f989b21@news.clspco.adelp hia.net>...
[color=blue]
> VC++ 6 simplifies the
> language to the point that quite a few ambiguities in the real language
> don't exist in its language.[/color]

Actually, you're right. It seems that this "trick" only works in the
case where the function parameter is something like

typename foo<T>::type

where foo<T>::type is dependent on T. Frankly, that is rather useless.

Nevermind. :)

- Shane
Closed Thread