From: Valery
Subject: CL vs C++ (problems with virtual template member functions in C++)
Date:
Message-ID: <3f5eea2b$1@shknews01>
Hi Lispers,
below go context and question.
1. Context
I know there is a plenty of Lispers reading good in C++. Some of
them do know an old irksome issue in C++ that virtual template
member functions are not supported. For example, it makes
impossible the following nice "manifest typing" style in C++
programming:
// --------- start of example ------------
#include <vector>
struct aTypelessData // a base "typeless" class. Some conversion
// abilities are expected to be
// implemented in derived classes
{
template<class SomeConcreteType>
virtual void try_to_convert_to(SomeConcreteType& output) const {
throw "this conversion is not implemented";
}
};
// a concrete type implemented basing on `double':
struct aDoubleVec : public aTypelessData {
vector<float> vec;
template<>
virtual void try_to_convert_to(class aIntVec& output) const {
... // convert double to int
}
};
// a concrete type implemented basing on `int'
struct aIntVec : public aTypelessData {
vector<int> vec;
template<>
virtual void try_to_convert_to(class aIntVec& output) const {
... // nothing to convert, thus just copy
}
};
// function which makes integer-based arithmetics with two given objects
// of a priori unknown types
void my_fast_int_function(const aTypelessData& a,
const aTypelessData& b,
aIntVec &res)
{
try {
aIntVec ivec1, ivec2;
a.try_to_convert_to(ivec1); // object `a' should know how to
// convert himself to a target
// type aIntVec
b.try_to_convert_to(ivec2); // object `b' should know how to
// convert himself to a target
// type aIntVec
// here go my fast integer arithmetics for ivec1 and ivec2
...
}
catch(...) {
// conversion is not possible
}
}
main() {
aIntVec iresult;
aIntVec ivec;
aDoubleVec dvec;
my_fast_int_function(ivec, dvec, iresult); // so this function is not
// restricted for certain
// types
}
// --------- end of example ------------
BTW, similar problems come for data I/O, when type of the data being
read is not known yet (and even *not* needed up to a certain
last moment!)
I guess Common Lisp shouldn't have this type of boring restriction.
2. Question
How the above given example could look in CLOS?
P.S. please make a Cc to me: v.khamenia AT biovision-discovery DOT de
Thank you.
Best regards,
Valery A.Khamenya
Valery <········@mail.ru> wrote in message news:<··········@shknews01>...
> I know there is a plenty of Lispers reading good in C++. Some of
> them do know an old irksome issue in C++ that virtual template
> member functions are not supported. For example, it makes
> impossible the following nice "manifest typing" style in C++
> programming:
>
[ snip ]
>
> How the above given example could look in CLOS?
Are you asking how an impossible C++ example would look like in CLOS?
Does that mean you want a possible CLOS example or an impossible CLOS
example?
Should impossibility be retained in the translation, or ironed away?
This is something like translating Lewis Carrol's poem ``Jabberwocky''
to German or French.
We first have to identify what kind of impossibility in CLOS resembles
the restriction regarding virtual template functions in C++. ;)
This is is a clash between the static and dynamic world. In Lisp,
there are examples of this: for instance you can't FUNCALL over a
macro.
Okay, how about:
;; define ``virtual function'' by indirecting
(defun expand-template-method (type-left type-right)
(let ((defmethod-params `(multiply ((a ,type-left) (b
,type-right))
(* a b))))
(apply #'defmethod defmethod-params)))
Or something... :)
It's just a draft to see if i understood you well :
;;; using CLOS to simulate C++ template and virtual template method
;;; Corman Common Lisp 2.01
;;; i used char instead of double to see more clearly (i hope!) the point
;;; so 'cvec' is used instead of dvec & aCharVec instead of aDoubleVec
;;; it's very dirty...
(defclass aTypelessData)
(defclass aIntVec (aTypelessData)) ; todo: use macros to
(defclass aCharVec (aTypelessData)) ; simulate template
;; todo: constructeur
;; todo: method set-all, init from a list
;; todo: method get-list, get the corresponding list
(defmethod try_to_convert_to ((from aTypelessData) (to aIntVec))
(throw 'error "conversion impossible") )
(defmethod try_to_convert_to (from aIntVec) (to aIntVec)
;; todo: copy
)
(defmethod try_to_convert_to (from aCharVec) (to aIntVec)
;; todo: copy & convert char->int
)
(defun main ()
(let ((iresult (make-aIntVec))
(ivec (make-aIntVec '(1 2)))
(cvec (make-aCharVec '(#\a #\b))) )
(my_fast_int_function ivec cvec iresult) ))
(defmethod my_fast_int_function (a aTypelessData) (b aTypelessData) (res aIntVec)
(format t
(catch 'error
(let ((ivec1 (make-aIntVec))
(ivec2 (make-aIntVec)) )
(try_to_convert_to a ivec1)
(try_to_convert_to b ivec2)
(set-all res (mapcar #'+ (get-list ivec1) (get-list ivec2)))
;; todo: string of the result
))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@+