Template type deduction issues

D

Dilip

I am sure this is going to turn out to be a dumb question but here goes
anyway.
I was trying out the Hello World equivalent of a template program that
determines whether the type passed is a class type. This example is
lifted straight out of C++ Templates by Josuttis et al. However I
can't get it to compile with VC++ 2005. Here is what I tried:

template<typename T>
class IsClassT
{
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};

struct Idiot
{
};

int main()
{
if (IsClassT<Idiot>::Yes)
std::cout << "Hurray!\n";

return 0;
}

The compiler complains:

1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2783: 'IsClassT<T>::Two IsClassT<T>::test(...)' : could not
deduce template argument for 'C'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(508)
: see declaration of 'IsClassT<T>::test'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(520)
: see reference to class template instantiation 'IsClassT<T>' being
compiled
1> with
1> [
1> T=Idiot
1> ]
1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2784: 'IsClassT<T>::One IsClassT<T>::test(int C::* )' : could
not deduce template argument for 'int C::* ' from 'int'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(507)
: see declaration of 'IsClassT<T>::test'
1> with
1> [
1> T=Idiot
1> ]
1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2056: illegal expression

I thought promoting a zero integral constant to a pointer is preferred
over ellipsis?

thanks!
 
V

Victor Bazarov

Dilip said:
I am sure this is going to turn out to be a dumb question but here
goes anyway.

[...example of VC++ 2005 failing snipped...]

I thought promoting a zero integral constant to a pointer is preferred
over ellipsis?

It is most likely a bug in VC++. Have you tried asking in the VC++ NG
(microsoft.public.vc.language), maybe it's already known?

V
 
A

amparikh

Dilip said:
I am sure this is going to turn out to be a dumb question but here goes
anyway.
I was trying out the Hello World equivalent of a template program that
determines whether the type passed is a class type. This example is
lifted straight out of C++ Templates by Josuttis et al. However I
can't get it to compile with VC++ 2005. Here is what I tried:

template<typename T>
class IsClassT
{
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};

struct Idiot
{
};

int main()
{
if (IsClassT<Idiot>::Yes)
std::cout << "Hurray!\n";

return 0;
}

The compiler complains:

1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2783: 'IsClassT<T>::Two IsClassT<T>::test(...)' : could not
deduce template argument for 'C'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(508)
: see declaration of 'IsClassT<T>::test'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(520)
: see reference to class template instantiation 'IsClassT<T>' being
compiled
1> with
1> [
1> T=Idiot
1> ]
1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2784: 'IsClassT<T>::One IsClassT<T>::test(int C::* )' : could
not deduce template argument for 'int C::* ' from 'int'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(507)
: see declaration of 'IsClassT<T>::test'
1> with
1> [
1> T=Idiot
1> ]
1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2056: illegal expression

I thought promoting a zero integral constant to a pointer is preferred
over ellipsis?

thanks!

I encountered a similar problem few weeks back. I was about to enter a
bug when I saw a bug already entered on similar lines.

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99405
 
A

amparikh

Dilip said:
I am sure this is going to turn out to be a dumb question but here goes
anyway.
I was trying out the Hello World equivalent of a template program that
determines whether the type passed is a class type. This example is
lifted straight out of C++ Templates by Josuttis et al. However I
can't get it to compile with VC++ 2005. Here is what I tried:

template<typename T>
class IsClassT
{
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};

struct Idiot
{
};

int main()
{
if (IsClassT<Idiot>::Yes)
std::cout << "Hurray!\n";

return 0;
}

The compiler complains:

1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2783: 'IsClassT<T>::Two IsClassT<T>::test(...)' : could not
deduce template argument for 'C'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(508)
: see declaration of 'IsClassT<T>::test'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(520)
: see reference to class template instantiation 'IsClassT<T>' being
compiled
1> with
1> [
1> T=Idiot
1> ]
1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2784: 'IsClassT<T>::One IsClassT<T>::test(int C::* )' : could
not deduce template argument for 'int C::* ' from 'int'
1> with
1> [
1> T=Idiot
1> ]
1>
c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(507)
: see declaration of 'IsClassT<T>::test'
1> with
1> [
1> T=Idiot
1> ]
1>c:\work\workarea\allpurposeconsoleapp\allpurposeconsoleapp\allpurposeconsoleapp.cpp(510)
: error C2056: illegal expression

I thought promoting a zero integral constant to a pointer is preferred
over ellipsis?

thanks!

Of course, I got around the problem by making the member template test
to a non-template member function.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top