 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Victor Bazarov Guest
|
Posted: Tue Jan 24, 2006 7:16 am Post subject: Re: Template specialisation and base classes |
|
|
Earl Purple wrote:
| Quote: | Victor Bazarov wrote:
I don't follow. So, provide traits-type function for Bar as well,
and it is going to be chosen over the generic template definition.
The template argument type deduction produces the _exact_ match. If
you want to change that, you need to (a) provide a compelling
argument describing what problem it solves that cannot be solved by
existing features of the language and (b) convince everybody that
your change doesn't break any of the existing code or that such
breakage is a small price to pay for all the benefits your solution
brings. Here I see neither, sorry.
Are the language rules to make life easy for the programmer or for the
compiler writers?
|
Both. The language is full of trade-offs.
| Quote: | I know that export templates were considered too
hard for compiler writers which is why the rules are as they are with
templates.
|
Not only 'export' is the problem. There are other places (like name
lookup) where rules for templates are different from rules for regular
functions and classes, IIRC.
| Quote: | But anyway, here is an example of where you might want it. Now suppose
we want a smart pointer that clones (maybe implements copy-on-write).
The difficulty here is how to make the copy without making our
smart-pointer intrusive (forcing the user to inherit from a clone
type) and also to allow 3rd-party types where the normal copy method
is a general copy-constructor.
Now although we are allowed co-variant return types, it would be
impossible to implement here so we'll create a generic function:
template < typename T
do_clone( T* src, T* & dest )
|
I guess you mean
void do_clone( T* src, T* & dest )
| Quote: | {
dest = new T( *src );
}
Now suppose I have a type that uses a member clone() function. Then
our routine would be:
template
do_clone( clone_base * src, clone_base * & dest )
|
void do_clone( ...
| Quote: | {
dest = src->clone();
}
and the smart-pointer can be implemented with do_clone<T> and work
automatically even with derived-classes from do_clone. (But at the
same time not enforce the user to derive from clone_base and classes
that
use another method that isn't clone() will be able to specialise
do_clone externally for that particular group).
|
Now, it seems that you're trying to solve a particular problem, and
for that you're looking to change the language. Doesn't seem fair
to all who (a) have other problems to solve using existing mechanisms
and (b) who don't really care for your particular problem. No?
To solve what you have you can rely on SFINAE. If the class T does
not have 'clone' member, you just fall back onto another definition:
template<class T> void do_clone(T* s, T*& d ...)
{
d = new T(*s);
}
struct clone_base
{
virtual clone_base* clone() const = 0;
};
struct clone_too : clone_base
{
clone_base* clone() const { return new clone_too(*this); }
};
void do_clone(clone_base* s, clone_base *& d,
clone_base* (clone_base::*)() const = &clone_base::clone)
{
d = s->clone();
}
struct no_clone {
};
int main()
{
clone_base* p = new clone_too();
clone_base* pp;
do_clone(p, pp);
no_clone *np = new no_clone(), *npp;
do_clone(np, npp);
}
In this particular situation, 'clone_base' has 'clone' member of
a specific signature. I may have screwed up somewhere, but it seems
what you're looking for. If not, explain further. I recomend,
however, to move to 'comp.lang.c++' where you'd inquire how to solve
your problem using existing C++ means instead of suggesting to change
the language.
V
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Earl Purple Guest
|
Posted: Tue Jan 24, 2006 6:15 pm Post subject: Re: Template specialisation and base classes |
|
|
Victor Bazarov wrote:
| Quote: | Now, it seems that you're trying to solve a particular problem, and
for that you're looking to change the language. Doesn't seem fair
to all who (a) have other problems to solve using existing mechanisms
and (b) who don't really care for your particular problem. No?
|
It was an example of a case where such a change would be useful. It is
not necessarily the only example where it might be useful.
| Quote: | To solve what you have you can rely on SFINAE.
|
A technique I could presumably google for. What exactly is SFINAE
though? I guess some kind of adapter as you go on to...
If the class T does
| Quote: | not have 'clone' member, you just fall back onto another definition:
template<class T> void do_clone(T* s, T*& d ...)
{
d = new T(*s);
}
struct clone_base
{
virtual clone_base* clone() const = 0;
};
struct clone_too : clone_base
{
clone_base* clone() const { return new clone_too(*this); }
};
void do_clone(clone_base* s, clone_base *& d,
clone_base* (clone_base::*)() const = &clone_base::clone)
{
d = s->clone();
}
struct no_clone {
};
|
| Quote: | int main()
{
clone_base* p = new clone_too();
clone_base* pp;
do_clone(p, pp);
no_clone *np = new no_clone(), *npp;
do_clone(np, npp);
}
In this particular situation, 'clone_base' has 'clone' member of
a specific signature. I may have screwed up somewhere, but it seems
what you're looking for. If not, explain further.
|
Andi f you screw up what chance does it give the rest of us (and all
those out there who are far lower in skill level even than me). The
idea of the change is to make life easier for the general programmer.
By the way, it is supposed to work for where you have a general type T
(in at template) that you want to clone and don't know how to clone it.
So you create a traits-type do_clone() function which can be
specialised. T could be std::string or it could be Bar derived from
clone_base or it could be Blob derived from a 3rd party base-class that
uses Clone() with a capital C.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
cnjinhao@hotmail.com Guest
|
Posted: Tue Jan 24, 2006 6:15 pm Post subject: Re: Template specialisation and base classes |
|
|
the following code could works well
#include <iostream>
class Foo;
char __fun(Foo*);
long __fun(...);
template<typename _T>
struct is_Foo
{
enum{value = sizeof(char) == sizeof(__fun((_T*)0)) };
};
class Foo
{
public:
virtual ~Foo() {}
};
template< typename T >
int value( const T* pT)
{
if(is_Foo<T>::value) //this statement will be optimized
return 1;
else
return 0;
}
class Bar : public Foo{};
int main()
{
Bar bar;
Foo* foo = &bar;
int *p;
std::cout << value( foo ) << ' ' << value( &bar ) << ' ' <<
value(p)<<'n';
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| 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
|
|