473,397 Members | 1,972 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

A problem about template?

Hi, guys

I am reading Vandevoorde and Josuttis 's "C++ Template The Complete
Guide" these days.

When I read the chapter 15: Traits and Policy classes.

I copy the code in 15.2.2 that use to determining the class type.

The code is below:
#include <iostream>

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

struct MyStruct{};
union MyUnion{};

int main()
{
std::cout << IsClassT<MyStruct>::Yes << std::endl
<< IsClassT<MyUnion>::Yes << std::endl;
return 0;
}

It can be compiled using the Comeau C/C++ 4.3.8 for ONLINE_EVALUATION
but it can't be compiled using the MS VC 8 and gcc version 3.4.2
(mingw-special)
the error message is:
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(54) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(65) : see reference to
class template instantiation 'IsClassT<T>' being compiled
1 with
1 [
1 T=MyStruct
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : 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=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(53) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyStruct
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2056: illegal
expression
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(54) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(66) : see reference to
class template instantiation 'IsClassT<T>' being compiled
1 with
1 [
1 T=MyUnion
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : 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=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(53) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyUnion
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2056: illegal
expression
1>Build log was saved at "file://d:\code\vc8_debug\sample\Debug
\BuildLog.htm"
1>sample - 6 error(s), 0 warning(s)

Why it can't be compiled using vc8 and gcc??

Mar 6 '07 #1
5 2518
On Mar 6, 6:16 pm, "Wayne Shu" <Wayne...@gmail.comwrote:
Hi, guys

I am reading Vandevoorde and Josuttis 's "C++ Template The Complete
Guide" these days.

When I read the chapter 15: Traits and Policy classes.

I copy the code in 15.2.2 that use to determining the class type.

The code is below:
#include <iostream>

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

};

struct MyStruct{};
union MyUnion{};

int main()
{
std::cout << IsClassT<MyStruct>::Yes << std::endl
<< IsClassT<MyUnion>::Yes << std::endl;
return 0;

}

It can be compiled using the Comeau C/C++ 4.3.8 for ONLINE_EVALUATION
but it can't be compiled using the MS VC 8 and gcc version 3.4.2
(mingw-special)
the error message is:
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(54) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(65) : see reference to
class template instantiation 'IsClassT<T>' being compiled
1 with
1 [
1 T=MyStruct
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : 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=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(53) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyStruct
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2056: illegal
expression
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(54) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(66) : see reference to
class template instantiation 'IsClassT<T>' being compiled
1 with
1 [
1 T=MyUnion
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : 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=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(53) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyUnion
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2056: illegal
expression
1>Build log was saved at "file://d:\code\vc8_debug\sample\Debug
\BuildLog.htm"
1>sample - 6 error(s), 0 warning(s)

Why it can't be compiled using vc8 and gcc??
For me the code looks with some strange logic.
C2783 error is because of the compiler cannot determine a template
argument.

AFAIK, enumerations are defined at compile time and also sizeof of
operator is valid only at compile time. not at runtime.

sizeof(fxn(0));
the above statement is neither making a function call nor validating
the size of return value. I dont know why sizeof returns '0' in this
case, but in the case of an empty class or structure, sizeof operator
returns 1 to avoid some unexpecte behavior that can be occured because
of returning size as 0. e.g is if we are declaring an array of empty
class, it should not be 0 right?

To verify that sizeof(fxn(0)); not making a function call, just
declare the function without defining its body. The linker will not
throw any linker error (even with your code if we make it compilable)
because the function call not happening anywhere. From this we can
veryfiy that there's nothing happening with such type of expression.
even if you define the body it will not be called.

There's another great example from Effective C++ that "Never re-define
the default paramemeter of a virtual funciton in the derived class.

e.g

class Base
{
public:
virtual void Test(COLOR c = RED); // Assume RED nad GREEN are
enumerations
};

class Derived: public Base
{
public:
void Test(COLOR c = GREEN)
}
What's the error in the above code is that you are creating a an
derived class object using base class pointer,

Base* p = new Derived;
p->Test();

when the compiler see the above, code it will replace the deafult
parameter with base class's value since the parameter defaulting is
doing at compiler time. this can cause some unexpected result.

So always differentiate between compile time and runtime operators.

Mar 6 '07 #2
Sarath wrote:
On Mar 6, 6:16 pm, "Wayne Shu" <Wayne...@gmail.comwrote:
>>I am reading Vandevoorde and Josuttis 's "C++ Template The Complete
Guide" these days.
I copy the code in 15.2.2 that use to determining the class type.
#include <iostream>

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

};

struct MyStruct{};
union MyUnion{};

int main()
{
std::cout << IsClassT<MyStruct>::Yes << std::endl
<< IsClassT<MyUnion>::Yes << std::endl;
return 0;

}

It can be compiled using the Comeau C/C++ 4.3.8 for ONLINE_EVALUATION
but it can't be compiled using the MS VC 8 and gcc version 3.4.2
(mingw-special)
the error message is:
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyStruct
1 ]
[snipped rest of error message]
For me the code looks with some strange logic.
C2783 error is because of the compiler cannot determine a template
argument.

AFAIK, enumerations are defined at compile time and also sizeof of
operator is valid only at compile time. not at runtime.
Right.
sizeof(fxn(0));
the above statement is neither making a function call nor validating
the size of return value. I dont know why sizeof returns '0' in this
case, but in the case of an empty class or structure, sizeof operator
returns 1 to avoid some unexpecte behavior that can be occured because
of returning size as 0. e.g is if we are declaring an array of empty
class, it should not be 0 right?
What should happen here is the following: The compiler sees a function
call to an un-qualified function called "fxn". There are two functions
that can be used for this:
IsClassT<MyStruct>::test<MyStruct>(int MyStruct::*) and
IsClassT<MyStruct>::test<MyStruct>(...)
Since MyStruct is a class, it is possible to cast the argument, "0" to
the type "int MyStruct::*", meaning a pointer to an int member of
MyStruct. This way both methods are considered as possible targets for
the name "fxn", so the compiler chooses the first one (as the compiler
will regard functions with ellipses always as last choice). Note that if
you pass a non-class argument into IsClassT, the first function cannot
be used and SFINAE cuts in.

Just a guess: Did you try to turn off Microsoft Extensions for the
compiling settings (I heard some rumours that those are in conflict with
some of the fancy template tricks that are used by boost, so this may
apply in your case as well).

Regards,
Stuart
Mar 6 '07 #3
On 3ÔÂ6ÈÕ, ÏÂÎç7ʱ56·Ö, Stuart Redmann <DerTop...@web.dewrote:
Sarath wrote:
On Mar 6, 6:16 pm, "Wayne Shu" <Wayne...@gmail.comwrote:
>I am reading Vandevoorde and Josuttis 's "C++ Template The Complete
Guide" these days.
I copy the code in 15.2.2 that use to determining the class type.
#include <iostream>
>template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename Cstatic One test(int C::*);
template<typename Cstatic Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
>};
>struct MyStruct{};
union MyUnion{};
>int main()
{
std::cout << IsClassT<MyStruct>::Yes << std::endl
<< IsClassT<MyUnion>::Yes << std::endl;
return 0;
>}
>It can be compiled using the Comeau C/C++ 4.3.8 for ONLINE_EVALUATION
but it can't be compiled using the MS VC 8 and gcc version 3.4.2
(mingw-special)
the error message is:
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyStruct
1 ]

[snipped rest of error message]
For me the code looks with some strange logic.
C2783 error is because of the compiler cannot determine a template
argument.
AFAIK, enumerations are defined at compile time and also sizeof of
operator is valid only at compile time. not at runtime.

Right.
sizeof(fxn(0));
the above statement is neither making a function call nor validating
the size of return value. I dont know why sizeof returns '0' in this
case, but in the case of an empty class or structure, sizeof operator
returns 1 to avoid some unexpecte behavior that can be occured because
of returning size as 0. e.g is if we are declaring an array of empty
class, it should not be 0 right?

What should happen here is the following: The compiler sees a function
call to an un-qualified function called "fxn". There are two functions
that can be used for this:
IsClassT<MyStruct>::test<MyStruct>(int MyStruct::*) and
IsClassT<MyStruct>::test<MyStruct>(...)
Since MyStruct is a class, it is possible to cast the argument, "0" to
the type "int MyStruct::*", meaning a pointer to an int member of
MyStruct. This way both methods are considered as possible targets for
the name "fxn", so the compiler chooses the first one (as the compiler
will regard functions with ellipses always as last choice). Note that if
you pass a non-class argument into IsClassT, the first function cannot
be used and SFINAE cuts in.

Just a guess: Did you try to turn off Microsoft Extensions for the
compiling settings (I heard some rumours that those are in conflict with
some of the fancy template tricks that are used by boost, so this may
apply in your case as well).
I have tried to compiled with turning off the language extensions be
turned off.
The same result.
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
If I delete "IsClassT<T>::" in this statement, it can be compiled in
vc8 and gcc too.
Regards,
Stuart- Òþ²Ø±»ÒýÓÃÎÄ×Ö -

- ÏÔʾÒýÓõÄÎÄ×Ö -
Regards.

Mar 6 '07 #4
>>>On Mar 6, 6:16 pm, "Wayne Shu" <Wayne...@gmail.comwrote:
>>>>I am reading Vandevoorde and Josuttis 's "C++ Template The Complete
Guide" these days.
I copy the code in 15.2.2 that use to determining the class type.
#include <iostream>
>>>>template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename Cstatic One test(int C::*);
template<typename Cstatic Two test(...);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
>>>>};
>>>>struct MyStruct{};
union MyUnion{};
>>>>int main()
{
std::cout << IsClassT<MyStruct>::Yes << std::endl
<< IsClassT<MyUnion>::Yes << std::endl;
return 0;
>>>>}
>>>>It can be compiled using the Comeau C/C++ 4.3.8 for ONLINE_EVALUATION
but it can't be compiled using the MS VC 8 and gcc version 3.4.2
(mingw-special)
the error message is:
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyStruct
1 ]
Wayne Shu wrote:
I have tried to compiled with turning off the language extensions be
turned off.
The same result.
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
If I delete "IsClassT<T>::" in this statement, it can be compiled in
vc8 and gcc too.
That's contrary to common sense, as the compiler will definitely not
gain any information about the template argument "C" if you leave out
the class scope. It looks like a compiler bug to me (there are certainly
a lot of errors in both Microsoft and Gnu compilers, so I'd rather trust
Comeau).

Stuart
Mar 6 '07 #5
On Mar 6, 1:16 am, "Wayne Shu" <Wayne...@gmail.comwrote:
Hi, guys

I am reading Vandevoorde and Josuttis 's "C++ Template The Complete
Guide" these days.

When I read the chapter 15: Traits and Policy classes.

I copy the code in 15.2.2 that use to determining the class type.

The code is below:
#include <iostream>

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

};

struct MyStruct{};
union MyUnion{};

int main()
{
std::cout << IsClassT<MyStruct>::Yes << std::endl
<< IsClassT<MyUnion>::Yes << std::endl;
return 0;

}

It can be compiled using the Comeau C/C++ 4.3.8 for ONLINE_EVALUATION
but it can't be compiled using the MS VC 8 and gcc version 3.4.2
(mingw-special)
the error message is:
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(54) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(65) : see reference to
class template instantiation 'IsClassT<T>' being compiled
1 with
1 [
1 T=MyStruct
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : 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=MyStruct
1 ]
1 d:\code\vc8_debug\sample\main.cpp(53) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyStruct
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2056: illegal
expression
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2783:
'IsClassT<T>::Two IsClassT<T>::test(...)' : could not deduce template
argument for 'C'
1 with
1 [
1 T=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(54) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(66) : see reference to
class template instantiation 'IsClassT<T>' being compiled
1 with
1 [
1 T=MyUnion
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : 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=MyUnion
1 ]
1 d:\code\vc8_debug\sample\main.cpp(53) : see declaration of
'IsClassT<T>::test'
1 with
1 [
1 T=MyUnion
1 ]
1>d:\code\vc8_debug\sample\main.cpp(56) : error C2056: illegal
expression
1>Build log was saved at "file://d:\code\vc8_debug\sample\Debug
\BuildLog.htm"
1>sample - 6 error(s), 0 warning(s)

Why it can't be compiled using vc8 and gcc??

There are some bugs with vc8 when using SFINAE techniques. I had
myself entered one sometime back and there were some entered by others
too.
Just do a search on the vstudio site.

Mar 6 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: CoolPint | last post by:
As a self-exercise, I am trying to write a generic Priority Queue, which would store any type and and accept any user-definable "priority" function. After much tinkering, I came up with...
1
by: BekTek | last post by:
I'm still confused about the template partial specialization which is used in many libraries.. due to lack of introduction for beginner.. Could you tell me about that in short? Thanks in...
5
by: Tony Johansson | last post by:
Hello experts! I have two class template below with names Array and CheckedArray. The class template CheckedArray is derived from the class template Array which is the base class This program...
1
by: suzy | last post by:
hi, i have created a aspx page template by creating a template.cs file which inherits from the page class. In this file I override the OnInit event and create a template in the form of a...
3
by: mca | last post by:
Hi everyone, I'm new to asp.net and i have a question about separating the html code from the programming code. i have an unknown numbers of entries in my table. I want to make a hyperlink...
8
by: sagi.perel | last post by:
I have tried to compile the following code on Win & Unix. Doesn't work on either. <----- CODE -----> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <vector> #include...
4
by: StephQ | last post by:
According to: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.4 , if my understanding is correct, in template<typename T> class Foo { friend void func (const Foo<T>& foo); }; ...
17
by: JohnQ | last post by:
Is that I can approximate using my ideal of a language in it. On the flip side, what I dislike most about it is all the flak/protecting-the-golden-calf one gets when using it that way. I think a...
3
by: goodmen | last post by:
I think the boost::concept_check is too complex. Here is my solution about static interface and concept. The static interface can be used as function param. It is just a proxy of the real...
4
by: parag_paul | last post by:
hi All , I am giving the pseudo code about the problem I am talking about . I have a class hiearchy which looks like this. class A; template <class X1, class X2class B : public A{}
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.