472,333 Members | 1,159 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

SFINAE compilation troubles

I've been trying to use the sfinae principle in some code and have been
getting many compiler errors. So I decided to try a very simplified
version to see if I had the idea correct. Here's the example:

#include <iostream>

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 };
};

class A
{
public:
int a;
};

int main()
{
using namespace std;

if(IsClassT<A>::Yes)
cout << "A is a class!" << endl;
if(IsClassT<A*>::Yes)
cout << "A* is a class too!" << endl;

return 0;
}

This you may recognize is copied DIRECTLY from "C++ Templates" by
Josuttis, at least the template part anyway.

This is supposed to work right? Why does it think it can't find the
"test" function? It looks like the compiler isn't matching either of
those overloads. Also, as neither of those "test" functions are
actually being called (sizeof doesn't actually call the function), code
doesn't need to be provided for them.

Please, any help would be GREATLY appreciated!! Posted below are the
error messages I got when compiling with g++ 3.2.2 and 3.4.2.

With g++ 3.2.2

sfinae.cxx:5: warning: all member functions in class `IsClassT<T>' are
private
sfinae.cxx: In instantiation of `IsClassT<A>':
sfinae.cxx:26: instantiated from here
sfinae.cxx:26: no method `IsClassT<A>::test<A>'
sfinae.cxx:26: enumerator value for `Yes' not integer constant
sfinae.cxx: In instantiation of `IsClassT<A*>':
sfinae.cxx:28: instantiated from here
sfinae.cxx:28: no method `IsClassT<A*>::test<A*>'
sfinae.cxx:28: enumerator value for `Yes' not integer constant

With g++ 3.4.2:

sfinae.cxx:12: error: expected primary-expression before '>' token
sfinae.cxx: In instantiation of `IsClassT<A>':
sfinae.cxx:26: instantiated from here
sfinae.cxx:12: error: enumerator value for `Yes' not integer constant
sfinae.cxx: In instantiation of `IsClassT<A*>':
sfinae.cxx:28: instantiated from here
sfinae.cxx:12: error: enumerator value for `Yes' not integer constant

Jul 23 '05 #1
3 1778
ju****************@gmail.com wrote:
[SNIP]
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 };
}; [SNIP] Josuttis, at least the template part anyway.

[SNIP]

I was able to "fix" it this way:
enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == 1 };
Note the template keyword before the test function name. I am not sure it
is needed there, I have guessed that somehow g++ does not understand that
IsClassT<T>::test is a template name.

Comeau online compiles it both ways, which is weird. I suggest you look
around on the books' web for the errata, you may find a comment there
explaining the problem of g++.

Attila
Jul 23 '05 #2
Thanks so much for the response.

Your fix does indeed compile fine with 3.4.2, but not with 3.2.2. Is
this simply a compiler bug that was fixed somewhere between
3.2.2-3.4.2?

Oddly enough, that code now compiles on the Sun compiler v6U2. It
doesn't work according to the standard however. IsClassT<A>::Yes
returns false. It seems to match the (...) version of test before the
one with the pointer to a member. Not the first bug I've found in Sun's
compiler (at least the earlier versions anyway).

Justin

Jul 23 '05 #3
ju****************@gmail.com wrote:
Thanks so much for the response.

Your fix does indeed compile fine with 3.4.2, but not with 3.2.2. Is
this simply a compiler bug that was fixed somewhere between
3.2.2-3.4.2?
I have no idea. :-) I am inclined to suspect that it is rather 3.4.2 which
is at fault, but I only base my quess on what Comeau does in strict mode.
Of course this can be some sort of corner case, as Comeau accepts both forms
(the one with and without the template keyword).

As for the differences betweem 3.2.2 and 3.4.2, I think (but I may be wrong)
that 3.4.2 has a new C++ parser and has also introduced two phase name
lookup for templates. Any of those two is good enough cause for such a
change in behavior.
Oddly enough, that code now compiles on the Sun compiler v6U2. It
doesn't work according to the standard however. IsClassT<A>::Yes
returns false. It seems to match the (...) version of test before the
one with the pointer to a member. Not the first bug I've found in
Sun's compiler (at least the earlier versions anyway).


What I know as error in v6u2 was an error introduced in the 6 series, a name
mangling problem with function signatures containing const arguments passed
by value. The template support is better with v6, but it has its little
problems, so some things just won't compile (or work).

--
Attila aka WW
Jul 23 '05 #4

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

Similar topics

8
by: Peter Collingbourne | last post by:
Hello I am trying to do some template metaprogramming involving enabling or disabling a method in a parameterised class based on some condition....
2
by: Clark S. Cox III | last post by:
I'm writing a class that, depending on a template parameter, has constructors that take differing numbers of arguments. I initially thought that I...
1
by: Dilip | last post by:
I am a little confused about the difference between SFINAE and unambiguous overload resolution set. For ex: template<typename Tvoid func(T);...
6
by: edd | last post by:
Hello all, Is there a way to determine whether a particular type supports the -> operator at compile time? I'm trying to write a template...
3
by: none | last post by:
I am trying to understand SFINAE based on this wiki page: http://en.wikipedia.org/wiki/SFINAE // Defines return type to be void for all...
5
by: Fei Liu | last post by:
Hello, I just hit a strange problem regarding SFINAE. The following code causes compile error (void cannot be array element type), I thought SFINA...
2
by: Barry | last post by:
The problem brought by one earlier post from comp.lang.c++ http://groups.google.com/group/comp.lang.c++/browse_thread/thread/bf636c48b84957b/ I...
35
by: James Kanze | last post by:
Just ran into an interesting question concerning SFINAE. Given the following code: #include <iostream> #include <typeinfo> template<...
0
by: greek_bill | last post by:
Hi, I have a template function for which I use SFINAE to restrict one of the parameters. Then I also have a partial specialization of this...
0
by: concettolabs | last post by:
In today's business world, businesses are increasingly turning to PowerApps to develop custom business applications. PowerApps is a powerful tool...
0
better678
by: better678 | last post by:
Question: Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct? Answer: Java is an object-oriented...
0
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: CD Tom | last post by:
This happens in runtime 2013 and 2016. When a report is run and then closed a toolbar shows up and the only way to get it to go away is to right...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...

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.