Template type deduction issues

Discussion in 'C++' started by Dilip, Aug 17, 2006.

  1. Dilip

    Dilip Guest

    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!
    Dilip, Aug 17, 2006
    #1
    1. Advertising

  2. Dilip wrote:
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 17, 2006
    #2
    1. Advertising

  3. Dilip

    Guest

    Dilip wrote:
    > 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
    , Aug 17, 2006
    #3
  4. Dilip

    Guest

    Dilip wrote:
    > 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.
    , Aug 18, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fei Liu
    Replies:
    0
    Views:
    423
    Fei Liu
    Oct 25, 2007
  2. Fei Liu
    Replies:
    4
    Views:
    776
    Victor Bazarov
    Oct 26, 2007
  3. C++Liliput
    Replies:
    2
    Views:
    785
    James Kanze
    Oct 24, 2008
  4. er
    Replies:
    5
    Views:
    1,278
  5. Replies:
    2
    Views:
    323
Loading...

Share This Page