texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Texmacs-dev] [Announce] nogencc-15 released


From: David Allouche
Subject: Re: [Texmacs-dev] [Announce] nogencc-15 released
Date: Mon, 22 Jul 2002 18:05:33 +0200

On Monday 22 July 2002 16:42, Joris van der Hoeven wrote:
> On Mon, 22 Jul 2002, David Allouche wrote:
> > On Monday 22 July 2002 13:24, Joris van der Hoeven wrote:
> > > Je suis en train de tester un peu plus le code mathématique
> > > dans TeXmacs-misc. Il y a également un problème de compilation
> > > quand on replace test4 par test1 ou test6 à la fin de
> > > Univariate/Test/test2.cc
> >
> > Je préfèrerais que tu comprennes et corriges ces problèmes toi même.
>
> Je veux bien faire cet effort pour le code nettoyé,

I believe that all code which is related to TeXmacs in the
TeXmacs-misc package is perfectly clean.


> mais j'ai un peu de mal à comprendre ce que tu as voulu
> faire dans ce fichier très particulier test2.cc.
> Ca serait donc bien que tu m'aides un peu et que l'on en discute.
> Par exemple, je ne comprends pas le pourquoi de déclarer
> les fonctions test1/7 comme des templates.

Ha! I admit that part *is* tricky.

In the original code, some of those functions where compiled
conditionally depending on wether the "divisible" symbol was defined.
That is required because those function use some operators which are
not defined for all types.

To provide support for this feature in C++ we must templatize those
"conditionnaly compiled" function. Here we use the feature that no
semantic check (not even symbol lookup) is performed on templates
which are not instanciated. That trick is reminiscent of another trick
called "compile-time dispatch" which is used where I defined local
structs called "internal".

Those functions which did not need conditional compilation were also
templatized to provide a uniform interface.

A great book which made me discover those features (and much more) is
"Modern C++ Design" by Andrei Alexandrescu. I am sure after you read
that book you will change you mind about templates. They provide a
real metalinguistic facility, and it is built into the language.

> Aussi, étant donné
> que l'on est passé aux templates, on pourrait peut-être remplacer
>
>       #define series<int_mod<1234577> >
>
> par
>
>       #define series<CST>
>
> Est-ce que c'est permis ? Peut être qu'il serait encore mieux de faire
> un
>
>       typedef int_mod<1234577> CST;

I prefer that latter form, but I did not make the change for fear you
tag them as unecessary.

> > Il s'agit très probablement d'erreurs de résolution de surcharge qui
> > sont dus à la place particulière des templates dans l'algorithmes de
> > résoltion de surcharge du C++.
>
> Tu peux nous exmpliquer brièvement quels peuvent être les problèmes
> avec la résolution de surcharge en relation avec les templates ?
> (Désolé, mais je n'ai pas encore eu le temps d'acheter le livre
> que tu m'as conseillé...)

The probleme here is that operators are defined as

  template<class C> series<C> operator * (series<C>, series<C>);

implicit_but<C> does not inherits for series<C>, in the previous code
the overload resolution was done by implicitely using
implicit_series_C::operator series_C (). But "if a template function
argument has been determined by template argument deduction [which is
always true for operator used in infix style] that argument cannot
also have promotions, standard conversions or user-defined conversion
applied." (TC++PL3 section 13.3.2).

That could be fixed by defining something like:

  template<class C> implicit_series<C>
  operator * (type_x f, type_y g) {
    return series<C>(f) * series<C>(g); }

where type_x and type_y are any combination of implicit_series<C> and
series<C>. But one clearly see that approach does not scale.

> > Le correctif simple est d'effecture des
> > cast explicites vers SERIES, le bon correctif est de déplacer les
> > opérateurs sur series<C> pour être des membres de la classe
> > series<C>.
>
> C'est précisement le genre de correctif que je déteste :
> je n'aime pas voir les opérateurs sur series<C> comme fonctions
> membres. Enfin, si on ne peut pas faire autrement...

I know you do not like that, but that is the right way to do it.

The point here is that when (say) operator* is a member of a template
class, the template parameter is determined solely by the right hand
type of the member access operator. So the member operator parameter
will not contribute to template argument deduction, and thus will be
promoted, converted, etc...

To understand this you have to recall that

  A * B; // * is an overloaded operator defined in the class of A

is equivalent to

  A.operator*(B);

Actually, it would be better to have implicit_series<C> inherit from
series<C>, and consistently use passing of counted pointer parameters
as const references (to preserve pass by value semantics as well as
polymorphism). But that is quite a heavyweight restructuring.

-- 

                                  -- David --



reply via email to

[Prev in Thread] Current Thread [Next in Thread]