 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
υα Guest
|
Posted: Sun Apr 03, 2005 10:00 pm Post subject: has_member implementation(template metaprogramming) |
|
|
//Well,this one is,just like the title sais,about Template Metaprogramming.
// I am sorry,if it lready exists, but I had this idea today and tried it.
// Just follow the comments to understand.
typedef char Small;
typedef struct {char unused[2];} Big;
// or just whatever you like
// the first template parameter is the type to check,
// the second the supposed type of the member.
// Just like with checking for a nested class, just using
// the default parameter for SFINAE.Note that if there wasn't
// this second template parameter in the second function,
// then this function would always be chosen.
#define DEFINE_HAS_MEMBER_WITH_TYPE(name)
template <typename T,typename U>
struct has_member_##name##_with_type
{
private:
/* Note that in order to disambiguate the calls I need
the first dummy parameter.
*/
template <typename U,typename V>
static ::Small has_##name(int,V U::* = &U::name);
template <typename U,typename V>
static ::Big has_##name(...);
public:
enum{value=sizeof(has_member_##name##_with_type::template
has_##name<T,U>(0)
)==sizeof(::Small)};
}
// No comma intended,just like in the following class.
// You can add one if that's your wish.
// A little bit trickier,because of the conversion.
// Now it will even say that there is a member function foo,
// even if it is the member data.On the other hand, you don't need
// to specify the type.
#define DEFINE_HAS_MEMBER(name)
template <typename T>
struct has_member_##name
{
private:
template <typename U>
static ::Small has_##name(int,int U::* = reinterpret_cast<int
U::*>(&U::name));
template <typename U>
static ::Big has_##name(...);
public:
enum{value=sizeof(has_member_##name::template has_##name<T>(0))
==sizeof(::Small)};
}
// I would like to hear the people's opinion.
//I wouldalso like to note, that English isn't my native language,
// so sorry if I did any mistake.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Mon Apr 04, 2005 1:14 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
"υα" <efim.slobodov233432 (AT) arcor (DOT) de> writes:
| Quote: | //Well,this one is,just like the title sais,about Template Metaprogramming.
// I am sorry,if it lready exists, but I had this idea today and tried it.
// Just follow the comments to understand.
|
.....
| Quote: | // I would like to hear the people's opinion.
|
Well, I don't know what compiler you tried it on, but it doesn't
compile for me on a conforming compiler (illegal use of "::template").
Even after that's fixed, though, it can't work, because SFINAE only
applies to function types and *not* to default function argument
expressions.
Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++
"ComeauTest.c", line 55: error: class "x" has no member "z"
DEFINE_HAS_MEMBER(z);
^
detected during:
instantiation of "Small has_member_z<T>::has_z(int, int U::*)
[with T=x, U=x]" at line 55
instantiation of class "has_member_z<T> [with T=x]" at line 58
"ComeauTest.c", line 58: error: the size of an array must be greater than zero
char test2[!has_member_z<x>::value];
Oh, and a point of style: synthesizing has_##name function names is
really unnecessary complication. The name "test" would work just as
well or better.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Marko Guest
|
Posted: Mon Apr 04, 2005 4:10 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
υα wrote:
[snip]
| Quote: | #define DEFINE_HAS_MEMBER_WITH_TYPE(name)
[snip]
#define DEFINE_HAS_MEMBER(name)
[snip] |
Aside from the problems pointed out by David Abrahams...
There's been a number of threads about compile-time checking
for members lately. Just check out threads like "compile-time
discrimination of types" or "detecting existence of a member
function (SFINAE ?)" in clc++m. So, I'll once again note that
the most important problem is the open core isuue #339:
[url]http://www.open-std.org/jtc1/sc22/WG21/docs/cwg_active.html#339[/url]
Regards,
Vladimir Marko
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
υα Guest
|
Posted: Mon Apr 04, 2005 4:12 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
"υα" <efim.slobodov233432 (AT) arcor (DOT) de> ΣΟΟΒέΙΜ/ΣΟΟΒέΙΜΑ Χ ΞΟΧΟΣΤΡΘ ΣΜΕΔΥΐέΕΕ:
news:4250433e$0$11461$9b4e6d93 (AT) newsread2 (DOT) arcor-online.net...
| Quote: | //Well,this one is,just like the title sais,about Template
Metaprogramming.
// I am sorry,if it lready exists, but I had this idea today and tried it.
// Just follow the comments to understand.
typedef char Small;
typedef struct {char unused[2];} Big;
// or just whatever you like
// the first template parameter is the type to check,
// the second the supposed type of the member.
// Just like with checking for a nested class, just using
// the default parameter for SFINAE.Note that if there wasn't
// this second template parameter in the second function,
// then this function would always be chosen.
#define DEFINE_HAS_MEMBER_WITH_TYPE(name)
template <typename T,typename U>
struct has_member_##name##_with_type
{
private:
/* Note that in order to disambiguate the calls I need
the first dummy parameter.
*/
template <typename U,typename V>
static ::Small has_##name(int,V U::* = &U::name);
template <typename U,typename V>
static ::Big has_##name(...);
public:
enum{value=sizeof(has_member_##name##_with_type::template
has_##name<T,U>(0)
)==sizeof(::Small)};
}
// No comma intended,just like in the following class.
// You can add one if that's your wish.
// A little bit trickier,because of the conversion.
// Now it will even say that there is a member function foo,
// even if it is the member data.On the other hand, you don't need
// to specify the type.
#define DEFINE_HAS_MEMBER(name)
template <typename T>
struct has_member_##name
{
private:
template <typename U>
static ::Small has_##name(int,int U::* = reinterpret_cast<int
U::*>(&U::name));
template <typename U>
static ::Big has_##name(...);
public:
enum{value=sizeof(has_member_##name::template has_##name<T>(0))
==sizeof(::Small)};
}
// I would like to hear the people's opinion.
//I wouldalso like to note, that English isn't my native language,
// so sorry if I did any mistake.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
Well,now I see you are right.I did even more mistakes,e.g. shadowing the
template parameter.
Probably the tests worked because I only tried it with a few fundamental
types and a class having
this member. Where the "SFINAE" appeared to work.Still,thanks for your help.
P.S.:Would be nice if the compiler considered the default parameters while
using SFINAE.
And I know a "test" would be OK,I just think it's nicer that way.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
υα Guest
|
Posted: Tue Apr 05, 2005 7:37 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
"David Abrahams" <dave (AT) boost-consulting (DOT) com> ΣΟΟΒέΙΜ/ΣΟΟΒέΙΜΑ Χ ΞΟΧΟΣΤΡΘ
ΣΜΕΔΥΐέΕΕ: news:uwtrj2sq7.fsf (AT) boost-consulting (DOT) com...
| Quote: | "υα" <efim.slobodov233432 (AT) arcor (DOT) de> writes:
//Well,this one is,just like the title sais,about Template
Metaprogramming.
// I am sorry,if it lready exists, but I had this idea today and tried
it.
// Just follow the comments to understand.
....
// I would like to hear the people's opinion.
Well, I don't know what compiler you tried it on, but it doesn't
compile for me on a conforming compiler (illegal use of "::template").
Even after that's fixed, though, it can't work, because SFINAE only
applies to function types and *not* to default function argument
expressions.
Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++
"ComeauTest.c", line 55: error: class "x" has no member "z"
DEFINE_HAS_MEMBER(z);
^
detected during:
instantiation of "Small has_member_z<T>::has_z(int, int
U::*)
[with T=x, U=x]" at line 55
instantiation of class "has_member_z<T> [with T=x]" at line
58
"ComeauTest.c", line 58: error: the size of an array must be greater
than zero
char test2[!has_member_z<x>::value];
Oh, and a point of style: synthesizing has_##name function names is
really unnecessary complication. The name "test" would work just as
well or better.
|
So this also wouldn't work?
// the same stuff as above
#define DEFINE_HAS_MEMBER(name)
template <typename T>
struct has_member_##name
{
private:
template <typename U>
static char (&select_test_func(const U&))[1];
template <typename U>
static ::Small test(Selecter<sizeof(select_test_func(&U::name))>*);
template <typename U>
static ::Big test(...);
public:
enum{value=sizeof(test<T>(0))==sizeof(::Small)};
}
I tried this and my compiler told me:
| Quote: | In instantiation of `has_member_clone<HasClone>':
151 D:LeoC++DevC++temp.cpp instantiated from here
151 D:LeoC++DevC++temp.cpp call_expr cannot be mangled due to a defect
in the C++ ABI |
My compiler is g++ 3.4.2 .Now what on earth does this mean?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Tue Apr 05, 2005 7:39 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
υα wrote:
| Quote: | P.S.:Would be nice if the compiler considered the default parameters while
using SFINAE.
|
Well, maybe. On the other hand, instead of relying so heavily on
now-you-see-it-now-you-don't, it might be easier to have direct language
support for this sort of query.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
υα Guest
|
Posted: Wed Apr 06, 2005 7:29 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
So,now I got it.Halleluia!Sorry that I forgot to include the
Selector class in my last message, but I thought that it's
pretty obvious.
Try this one and see if it works. :-)
template <int> Selector;
____________________________
#define DEFINE_HAS_MEMBER(name)
template <typename T>
struct has_member_##name
{
private:
template <typename U>
static ::Small test(Selecter<sizeof(&U::name)>*);
template <typename U>
static ::Big test(...);
public:
enum{value=sizeof(test<T>(0))==sizeof(::Small)};
}
____________________________
It can be no simpler and it really works.
The only problem is that there is still
acompilation error if the member is
inaccessible(i.e. nonpublic).But otherwise
value is just either 0 or 1.
I tried it with the following types:
struct HasClone
{
void clone(){}
};
struct NoClone
{};
and of course the ol' good int.
DEFINE_HAS_MEMBER(clone);
has_member_clone<HasClone>::value==1;
has_member_clone<NoClone>::value==0;
has_member_clone<int>::value==0;
All of those of course true!!!!
It still would be easier and safer if
the language would support it
without the need to write overly complicated
templates.I hope C++0x will do this and much more
(justa joke).
What remains is checking for a member of a certain type.
P.S.: I hope my compiler is standard-comforming enough.
Thanks for replies!
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Wed Apr 06, 2005 7:33 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
Pete Becker wrote:
| Quote: | υα wrote:
P.S.:Would be nice if the compiler considered the default parameters while
using SFINAE.
Well, maybe. On the other hand, instead of relying so heavily on
now-you-see-it-now-you-don't, it might be easier to have direct language
support for this sort of query.
|
Are there proposals about that? Looks an interesting idea.
I know that VC7.1 has two non-standard extension keywords named
__if_exists/__if_not_exists, that work as follow (example taken from MS
documentation):
template<typename T>
class X : public T {
public:
void Dump() {
std::cout << "In X
__if_exists(T::Dump) {
T::Dump();
}
__if_not_exists(T::Dump) {
std::cout << "T::Dump does not exist" << std::endl;
}
}
};
How is this approach rated by the Gurus? Personally it makes me a bit
nervous, because it looks like a statement but behaves like an
#if/#endif, but I have to admit that it does the job quite niflty and
doesn't look too difficult to implement.
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
υα Guest
|
Posted: Wed Apr 06, 2005 7:34 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
Well, I have still found only two possible
implementations for the "DEFINE_HAS_MEMBER_WITH_TYPE"
thing.Neither are truly good.
1)IMHO it shouldn't be considered ,because the information
would only be availible at run-time.But there would be still
almost no performance penalty(it isn't typeid ).
The idea is using this functions:
template <typename T,typename U>
bool isSame(U& x)
{
return is_same<T,U>::value;
}
#define DEFINE_HAS_MEMBER_WITH_TYPE(name)
template <typename T,typename U>
struct name##_checker
{
static bool value=isSame<U>(&T::name);
};
template <typename T,typename U>
struct has_member_##name##_with_type
{
public:
enum{value=has_member_##name<T>::value
&& name##_checker<T,U>::value};
}
Just as I said,pretty much useless.
2)
#define DEFINE_HAS_MEMBER_WITH_TYPE(name)
template <typename T,typename U>
struct name##_checker
{
enum{value=is_same<typeof(&T::name),U>::value};
};
template <typename T,typename U>
struct has_member_##name##_with_type
{
public:
enum{value=if_<has_member_##name
name##_checker<T,U>,int_<0> >::type::value};
}
value is now a compile-time constant,but the cost...
The cost is the portability.Bill Gibbons idea for typeof
is very good, but it could be that some user-defined
type X wasn't registered.So I have to rely on some
future extension.
Another note:both require that has_member_##name is defined.
One can duplicate the code to eliminate dependencies.I hope
s.o. can find a better solution.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Wed Apr 06, 2005 8:41 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
Alberto Barbati wrote:
| Quote: | Pete Becker wrote:
υα wrote:
P.S.:Would be nice if the compiler considered the default parameters while
using SFINAE.
Well, maybe. On the other hand, instead of relying so heavily on
now-you-see-it-now-you-don't, it might be easier to have direct language
support for this sort of query.
Are there proposals about that? Looks an interesting idea.
|
Not that I know of. I've been waiting for an opportunity to take that
potshot at SFINAE, and this was it. <g> I think it's a really ugly hack.
| Quote: |
I know that VC7.1 has two non-standard extension keywords named
__if_exists/__if_not_exists, that work as follow (example taken from MS
documentation):
template<typename T
class X : public T {
public:
void Dump() {
std::cout << "In X
__if_exists(T::Dump) {
T::Dump();
}
__if_not_exists(T::Dump) {
std::cout << "T::Dump does not exist" << std::endl;
}
}
};
How is this approach rated by the Gurus? Personally it makes me a bit
nervous, because it looks like a statement but behaves like an
#if/#endif, but I have to admit that it does the job quite niflty and
doesn't look too difficult to implement.
|
There's a fair amount of discussion between library implementors and
compiler writers about how to avoid the huge compile-time overhead
imposed by some template metaprogramming techniques. None of it is
refined enough yet for public consumption.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Wed Apr 06, 2005 8:48 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
Alberto Barbati <AlbertoBarbati (AT) libero (DOT) it> writes:
| Quote: | Pete Becker wrote:
υα wrote:
P.S.:Would be nice if the compiler considered the default parameters while
using SFINAE.
Well, maybe. On the other hand, instead of relying so heavily on
now-you-see-it-now-you-don't, it might be easier to have direct language
support for this sort of query.
Are there proposals about that? Looks an interesting idea.
|
When and if we have "concepts", they should be able to express those notions.
| Quote: | I know that VC7.1 has two non-standard extension keywords named
__if_exists/__if_not_exists, that work as follow (example taken from MS
documentation):
template<typename T
class X : public T {
public:
void Dump() {
std::cout << "In X
__if_exists(T::Dump) {
T::Dump();
}
__if_not_exists(T::Dump) {
std::cout << "T::Dump does not exist" << std::endl;
}
}
};
How is this approach rated by the Gurus?
|
I'm not a Guru but I believe it is far too specialized and I rather
have it in a way I can express through the type system (i.e. overload).
(The last sentence does not mean I'm a now-you-see-it-now-you-don't
fanatic)
| Quote: | Personally it makes me a bit
nervous, because it looks like a statement but behaves like an
#if/#endif,
|
Yeah, just trade some hashes for more underbars ;-)
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Marko Guest
|
Posted: Wed Apr 06, 2005 9:41 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
υα wrote:
| Quote: | Well, I have still found only two possible
implementations for the "DEFINE_HAS_MEMBER_WITH_TYPE"
thing.Neither are truly good.
1)IMHO it shouldn't be considered ,because the information
would only be availible at run-time.But there would be still
almost no performance penalty(it isn't typeid ).
[snip] |
| Quote: | 2)
#define DEFINE_HAS_MEMBER_WITH_TYPE(name)
template <typename T,typename U>
struct name##_checker
{
enum{value=is_same<typeof(&T::name),U>::value};
};
[snip]
value is now a compile-time constant,but the cost...
The cost is the portability.Bill Gibbons idea for typeof
is very good, but it could be that some user-defined
type X wasn't registered.So I have to rely on some
future extension.
Another note:both require that has_member_##name is defined.
One can duplicate the code to eliminate dependencies.I hope
s.o. can find a better solution.
|
I thought I gave you all references you need. The threads
I wrote about give quite good solutions and do not rely on
"typeof". And pretty much anything has a portability problem
because the implementers make different decisions about the
open core issue #339 (such as gcc issuing that "call_expr
can not be mangled..." for anything non-trivial). For your
convenience here are some nice solutions working under gcc
3.4.2 (without macros, just for a member named "foo"):
#include <iostream>
#include <ostream>
struct no { };
struct yes { no no_[2]; };
// check for unambigous public member foo of any type
template <typename T>
struct has_foo{
template <int>
struct yes_holder { typedef yes type; };
template<typename>
static no test(...);
template <typename U>
static typename yes_holder<sizeof(&U::foo)>::type test(U*);
static const bool value= sizeof(yes)==sizeof(test<T>((T*)0));
};
// check for an unambigous public member foo of specified type
template <typename fooType,typename T>
struct has_typed_foo{
template <fooType>
struct yes_holder { typedef yes type; };
template<typename>
static no test(...);
template <typename U>
static typename yes_holder<&U::foo>::type test(U*);
static const bool value= sizeof(yes)==sizeof(test<T>((T*)0));
};
// usage examples -- classes
struct A { };
struct B { int foo; };
struct C : B { };
struct D {
void foo() { }
static void foo(int) { }
};
int main(){
// usage examples -- check for member foo of any type
std::cout << has_foo
std::cout << has_foo
std::cout << has_foo
// std::cout << has_foo
// usage examples -- check for member foo with specified type
std::cout << has_typed_foo
std::cout << has_typed_foo
std::cout << has_typed_foo
std::cout << has_typed_foo
std::cout << has_typed_foo
true
std::cout << has_typed_foo
true
return 0;
}
Private/protected and ambiguous members are a huge problem
that has been raised in a new thread "SFINAE HasMethod Traits
crashes on private methods". I was making a few tests with
gcc and I'm going to write a follow-up soon, so stay tuned.
Best,
Vladimir Marko
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ZMS Guest
|
Posted: Thu Apr 07, 2005 7:26 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
1. The source from 'υα' or "Vladimir Marko"
does not compile in MSVC7.1 (MSC1301)
resulting 'INTERNAL COMPILER ERROR".
Is there any workaround in that compiler
( except using __if_exists and __if_not_exists ) ?
2. Testing of a template member function like following,
template< typename Stream >
void Output( Stream& stream );
causes compilation error in both sources.
But __if_exists implementaion in MSVC like following,
template< typename T >
struct has_foo {
__if_exists( T::foo ) { static const bool value = true; }
__if_not_exists( T::foo ) { static const bool value = false; }
};
works fine.
Is there any workaround on this case in other compilers ?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Thu Apr 07, 2005 7:26 am Post subject: Re: has_member implementation(template metaprogramming) |
|
|
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net> writes:
| Quote: | Alberto Barbati <AlbertoBarbati (AT) libero (DOT) it> writes:
| Pete Becker wrote:
| > υα wrote:
|
| >>P.S.:Would be nice if the compiler considered the default parameters while
| >>using SFINAE.
|
| > Well, maybe. On the other hand, instead of relying so heavily on
| > now-you-see-it-now-you-don't, it might be easier to have direct language
| > support for this sort of query.
|
|
| Are there proposals about that? Looks an interesting idea.
When and if we have "concepts", they should be able to express those
notions.
|
Maybe as requirements, but I doubt they will work for introspection.
IMO explicit conformance declarations are necessary.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Marko Guest
|
Posted: Thu Apr 07, 2005 2:52 pm Post subject: Re: has_member implementation(template metaprogramming) |
|
|
ZMS wrote:
| Quote: | 1. The source from 'υα' or "Vladimir Marko"
does not compile in MSVC7.1 (MSC1301)
resulting 'INTERNAL COMPILER ERROR".
Is there any workaround in that compiler
( except using __if_exists and __if_not_exists ) ?
|
I don't have MSVC7.1, only the free "Microsoft Visual C++
Toolkit 2003" and a quick check revealed that has_typed_foo
works fine, but has_foo causes an ICE on instantiation.
As I wrote before, the code is not portable due to different
approaches implementers choose wrt. the core issue #339
(ICE may be an indication that this issue was not considered
at all in this version of compiler).
| Quote: | 2. Testing of a template member function like following,
template< typename Stream
void Output( Stream& stream );
causes compilation error in both sources.
But __if_exists implementaion in MSVC like following,
template< typename T
struct has_foo {
__if_exists( T::foo ) { static const bool value = true; }
__if_not_exists( T::foo ) { static const bool value = false; }
};
works fine.
Is there any workaround on this case in other compilers ?
|
Well, If we add the class
struct E{
template
void foo(T*) { }
};
the statements
std::cout << has_typed_foo
// false
std::cout << has_typed_foo
// true
work as expected with both gcc 3.4.2 and MSVC++ Toolkit 2003.
Since &E::foo is a(n infinite) set of functions gcc correctly
reports ambiguity when trying to test has_foo
fact that MS extension __if_exists doesn't care for ambiguity
clearly demonstrates that it's something completely different.
Regards,
Vladimir Marko
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|