Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

confusion about function "template" within a template class of another typename

31 views
Skip to first unread message

Soviet_Mario

unread,
Dec 7, 2019, 3:06:17 PM12/7/19
to
I fork here because this doubt about template is different
from the enum thread

I don't know how to code this situation, so I try to write
broken pseudocode that does not compile, hoping to be able
to explain better than with plain words ....

I have this situation


'tt' will be either double or FixedString (a fast wasty
string class for strings up to a maximum size which inside
has an "embedded" fixed array and an used field for shorter
strings to be copied for the exact extent, they are asciiZ
'\0' terminated for support of std functions)


template <typename tt> class Table
{
tt Dati [constMaxRighe] [constMaxColonne];

template <typename xx> Table <xx> ExtractSubTable \
(int * SelectedRowList, int * SelectedColumnList, \
int numRows, int numCols);
}

now assume that ExtractSubTable must exist in 4 specializations

from Table <double> to Table <double>
from Table <double> to Table <FixedString>
from Table <FixedString> to Table <double>
from Table <FixedString> to Table <FixedString>

assume also I would declare and define the body outside the
class header (it will be big)

is it possible to code the function ONCE and not four times ?
Overloaded operators are just defined for every possible
double <=> FixedString combinations, so a single generic
function could (I hope and guess) be coded once.

I am confused as how to declare it ....

template <typename tt> \
template <typename xx> Table <xx> \
Table <tt> :: ExtractSubTable \
(int * SelectedRowList, int * SelectedColumnList, \
int numRows, int numCols)
{
int TgtRow, TgtCol;
Table <xx> RetVal;
for (int Row = 0; Row < numRows; Row++)
{
tgtRow = SelectedRowList [Row];
for (int Col = 0; Col < numCols; Col++)
{
tgtCol = SelectedColList [Col];
// will operator = be chosen properly ?
RetVal.Dati [Row] [Col] = Dati [tgtRow] [tgtCol];
}
}
}

the declarators is tempted completely random, please explain
me the order of nesting, or even if a multiple template (I
believe not) like template <tt, xx> is due

and also, how to generate the four specialized
ExtractSubTable functions ?

I am confused in nested templates;
tnx



How to produce all four



--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)

Paavo Helde

unread,
Dec 7, 2019, 5:31:07 PM12/7/19
to
On 7.12.2019 22:06, Soviet_Mario wrote:
> I fork here because this doubt about template is different from the enum
> thread
>
> I don't know how to code this situation, so I try to write broken
> pseudocode that does not compile, hoping to be able to explain better
> than with plain words ....
>
> I have this situation
>
>
> 'tt' will be either double or FixedString (a fast wasty string class for
> strings up to a maximum size which inside has an "embedded" fixed array
> and an used field for shorter strings to be copied for the exact extent,
> they are asciiZ '\0' terminated for support of std functions)

So, reinventing std::string. Why?

>
>
> template <typename tt> class Table
> {
> tt Dati [constMaxRighe] [constMaxColonne];
>
> template <typename xx> Table <xx> ExtractSubTable \
> (int * SelectedRowList, int * SelectedColumnList, \
> int numRows, int numCols);

What's this obsession with backslashes and line continuation? It's not
needed beyond macro definitions.


> }
>
> now assume that ExtractSubTable must exist in 4 specializations
>
> from Table <double> to Table <double>
> from Table <double> to Table <FixedString>
> from Table <FixedString> to Table <double>
> from Table <FixedString> to Table <FixedString>

So, every FixedString will be convertible to double? What happens if it
is an empty string or "abc"? If it is restricted to be numeric why don't
you hold everything in double?

> assume also I would declare and define the body outside the class
> header (it will be big)

No, it will not be big, It will be two lines:

1. Extract subtable of the same type (one function call)
2. Convert it into the needed type (second function call).

This is called modular design. The functions implementing those two
lines might be larger, but the result will be less complex than your
design which attempts to do two things at once.

When you have got this working and the customer is not satisfied with
the performance, then you might need to look into ways how to improve
it. Note that it is not given that the your solution to do two things at
once in a function is the best solution.

>
> template <typename tt> \
> template <typename xx> Table <xx> \
> Table <tt> :: ExtractSubTable \
> (int * SelectedRowList, int * SelectedColumnList, \

Weird backslash obsession again...


Soviet_Mario

unread,
Dec 7, 2019, 6:29:22 PM12/7/19
to
Il 07/12/19 23:30, Paavo Helde ha scritto:
> On 7.12.2019 22:06, Soviet_Mario wrote:
>> I fork here because this doubt about template is different
>> from the enum
>> thread
>>
>> I don't know how to code this situation, so I try to write
>> broken
>> pseudocode that does not compile, hoping to be able to
>> explain better
>> than with plain words ....
>>
>> I have this situation
>>
>>
>> 'tt' will be either double or FixedString (a fast wasty
>> string class for
>> strings up to a maximum size which inside has an
>> "embedded" fixed array
>> and an used field for shorter strings to be copied for the
>> exact extent,
>> they are asciiZ '\0' terminated for support of std functions)
>
> So, reinventing std::string. Why?

no it's not : all stuff static or automatic, no malloc, no
new operator, no throw and so. At the cost of waste of space
(and negligible limitation due to natural fields size).

>
>>
>>
>> template <typename tt> class Table
>> {
>> tt Dati [constMaxRighe] [constMaxColonne];
>>
>> template <typename xx> Table <xx> ExtractSubTable \
>> (int * SelectedRowList, int * SelectedColumnList, \
>> int numRows, int numCols);
>
> What's this obsession with backslashes and line
> continuation? It's not needed beyond macro definitions.

how in the NG is to be reported line continuation ?
Underscore ?

>
>
>> }
>>
>> now assume that ExtractSubTable must exist in 4
>> specializations
>>
>> from Table <double> to Table <double>
>> from Table <double> to Table <FixedString>
>> from Table <FixedString> to Table <double>
>> from Table <FixedString> to Table <FixedString>
>
> So, every FixedString will be convertible to double?

all "selected" columns contain convertible data potentially
converted (all or part).
All other columns contain textual data to never be converted
(nor extracted).
If sth goes wrong it is not a design error but a user error,
trapped as such and suggesting to correct the selection.

> What
> happens if it is an empty string or "abc"?

throws an exception. In a grid some columns are processable
for calculations, others are Date-time, name, surname,
class/section and so. Only properly selected columns are
extracted back and forth.

> If it is
> restricted to be numeric why don't you hold everything in
> double ?

to have allow for an homogeneous complete table (a single
matrix of data) holding also textual data.
The "work" temporaries are actually of the Table <double>
kind, for calculations. But later are reinserted back in
initial positions.
Otherwise a table could be "order" dependent, which I don't
like. Numeric data can be placed in whichever order amongst
textual data (on a column basis).
Plus some replicated header rows (one per each class, I mean
a school class here not the C++ keywords).
I would not want a "variant-like" cell, with a further field
holding its type .... but this is not completely excluded
though. With a union it could be done limiting the waste.
To start with I have chosen to have either FixedStrings or
double cells.


The selection is done intersecating a list of active columns
and same-class rows. All selected columns are expected to
hold numeric data.
The Table <double> is generated from extraction, then
calculations. Than back-exported in textual complete table
for logging as text file report.

Again, I am translating an existing program in Gambas, but
with no particular restraints : the two are not expected to
exchange data. I am simply trying to port all from scratch
to C++.

Well, I could maintain a skeleton of Gambas just as a
wrapper to prepare some files and to set options to pass to
C++ program, as a script file, not a very tight interaction.

>
>> assume also I would declare and define the body  outside
>> the class
>> header (it will be big)
>
> No, it will not be big, It will be two lines:
>
> 1. Extract subtable of the same type (one function call)
> 2. Convert it into the needed type (second function call).
>
> This is called modular design. The functions implementing
> those two lines might be larger, but the result will be less
> complex than your design which attempts to do two things at
> once.
>
> When you have got this working and the customer is not

no there is not any customer. I am just trying to
"translate" a facility for personal use to C++, but not for
performance reason. The SW has grown to a size I have
difficulty maintaining in gambas. Always the same problem.
C++ forces me to be more tidy, when I manage to understand
well the synthax at least.

> satisfied with the performance, then you might need to look
> into ways how to improve it. Note that it is not given that
> the your solution to do two things at once in a function is
> the best solution.
>
>>
>> template <typename tt> \
>> template <typename xx> Table <xx> \
>> Table <tt> :: ExtractSubTable \
>> (int * SelectedRowList, int * SelectedColumnList, \
>
> Weird backslash obsession again...

what about the synthax rather ?
I dunno how to write a proper declaration....

Öö Tiib

unread,
Dec 7, 2019, 6:39:45 PM12/7/19
to
On Sunday, 8 December 2019 01:29:22 UTC+2, Soviet_Mario wrote:
> Il 07/12/19 23:30, Paavo Helde ha scritto:
> > On 7.12.2019 22:06, Soviet_Mario wrote:
> >>
> >> template <typename xx> Table <xx> ExtractSubTable \
> >> (int * SelectedRowList, int * SelectedColumnList, \
> >> int numRows, int numCols);
> >
> > What's this obsession with backslashes and line
> > continuation? It's not needed beyond macro definitions.
>
> how in the NG is to be reported line continuation ?
> Underscore ?

You mean that you broke line to keep your posting line length under
70 symbols and want to indicate it? Unsure about others
but when result compiles without those backslashes then I read it
better when you do not indicate it at all.

Soviet_Mario

unread,
Dec 7, 2019, 7:44:17 PM12/7/19
to
Il 08/12/19 00:39, Öö Tiib ha scritto:
> On Sunday, 8 December 2019 01:29:22 UTC+2, Soviet_Mario wrote:
>> Il 07/12/19 23:30, Paavo Helde ha scritto:
>>> On 7.12.2019 22:06, Soviet_Mario wrote:
>>>>
>>>> template <typename xx> Table <xx> ExtractSubTable \
>>>> (int * SelectedRowList, int * SelectedColumnList, \
>>>> int numRows, int numCols);
>>>
>>> What's this obsession with backslashes and line
>>> continuation? It's not needed beyond macro definitions.
>>
>> how in the NG is to be reported line continuation ?
>> Underscore ?
>
> You mean that you broke line to keep your posting line length under
> 70 symbols and want to indicate it?

I tried to broke down parts "logically" as much as possible,
but the arglist was too long all the same.

> Unsure about others
> but when result compiles without those backslashes then I read it
> better when you do not indicate it at all.

ok ...

Öö Tiib

unread,
Dec 7, 2019, 7:46:20 PM12/7/19
to
On Saturday, 7 December 2019 22:06:17 UTC+2, Soviet_Mario wrote:
> I am confused as how to declare it ....
>
> template <typename tt> \
> template <typename xx> Table <xx> \
> Table <tt> :: ExtractSubTable \
> (int * SelectedRowList, int * SelectedColumnList, \
> int numRows, int numCols)
> {
> int TgtRow, TgtCol;
> Table <xx> RetVal;
> for (int Row = 0; Row < numRows; Row++)
> {
> tgtRow = SelectedRowList [Row];
> for (int Col = 0; Col < numCols; Col++)
> {
> tgtCol = SelectedColList [Col];
> // will operator = be chosen properly ?
> RetVal.Dati [Row] [Col] = Dati [tgtRow] [tgtCol];

I trust it will.

> }
> }
> }
>
> the declarators is tempted completely random, please explain
> me the order of nesting, or even if a multiple template (I
> believe not) like template <tt, xx> is due

I do not understand where you said what is wrong with it.

> and also, how to generate the four specialized
> ExtractSubTable functions ?

Since C++ cant deduce what you want to call you need to
explicitly instantiate

othervar = tablevar.ExtractSubTable<FixedString>(a,b,c,d);

> I am confused in nested templates;
> tnx

See
<https://en.cppreference.com/w/cpp/language/member_template>
for simple reference.

>
> How to produce all four

I dislike implicit conversions even between close enough types like
double and int. Sometimes tiny typos compile because of it,
are hard to notice in longer expressions, cause confusion about
what went wrong and so slow down programming.
Fortunately compilers have started to warn about those. But your
idea of user defined implicit conversions between double and string
feel like deliberately adding that kind of pain to yourself.

Soviet_Mario

unread,
Dec 8, 2019, 6:15:41 AM12/8/19
to
Il 08/12/19 01:46, Öö Tiib ha scritto:
TNX, I'm going reading

>
>>
>> How to produce all four
>
> I dislike implicit conversions even between close enough types like
> double and int. Sometimes tiny typos compile because of it,
> are hard to notice in longer expressions, cause confusion about
> what went wrong and so slow down programming.
> Fortunately compilers have started to warn about those. But your
> idea of user defined implicit conversions between double and string
> feel like deliberately adding that kind of pain to yourself.
>

well, as the two types are not implicitely convertible at
all, every conversion must pass through the operators I have
manually coded, so it is not actually "implicit".
Operators fail and throw an exception if a FixedString does
not hold a valid double textual representation as recognized
by scanf for example or strtod.
But this originates by a wrong selection of columns on which
to work or by wrong input by user, the program cannot do
anything except signalling it

Öö Tiib

unread,
Dec 8, 2019, 7:38:52 AM12/8/19
to
On Sunday, 8 December 2019 13:15:41 UTC+2, Soviet_Mario wrote:
> Il 08/12/19 01:46, Öö Tiib ha scritto:
> >
> > I dislike implicit conversions even between close enough types like
> > double and int. Sometimes tiny typos compile because of it,
> > are hard to notice in longer expressions, cause confusion about
> > what went wrong and so slow down programming.
> > Fortunately compilers have started to warn about those. But your
> > idea of user defined implicit conversions between double and string
> > feel like deliberately adding that kind of pain to yourself.
> >
>
> well, as the two types are not implicitely convertible at
> all, every conversion must pass through the operators I have
> manually coded, so it is not actually "implicit".

There are no difference really if implicit conversions are
written by programmer or inbuilt into language. Programmer
needs to make those explicit explicitly by using keyword
"explicit". ;)

> Operators fail and throw an exception if a FixedString does
> not hold a valid double textual representation as recognized
> by scanf for example or strtod.

The nature of problem is not about processing data wrongly by
mistake of end user but programmer doing typos.
The more there are conversions the more there are chances that
something can be misused in wrong role in code by typo.
Typo like adding something not to array element but to
pointer into what array itself did decay. When programmer runs
it and sees that something is wrong then he sometimes stares
half an hour at code since there were no warnings.

> But this originates by a wrong selection of columns on which
> to work or by wrong input by user, the program cannot do
> anything except signalling it

That is usual case. When I let user to index something I use
the at() member of containers for to have exception to report
when they violate bounds. But it wasn't what I meant.

Paavo Helde

unread,
Dec 8, 2019, 7:59:13 AM12/8/19
to
On 8.12.2019 1:29, Soviet_Mario wrote:
> Il 07/12/19 23:30, Paavo Helde ha scritto:
>> On 7.12.2019 22:06, Soviet_Mario wrote:
>>> I fork here because this doubt about template is different from the enum
>>> thread
>>>
>>> I don't know how to code this situation, so I try to write broken
>>> pseudocode that does not compile, hoping to be able to explain better
>>> than with plain words ....
>>>
>>> I have this situation
>>>
>>>
>>> 'tt' will be either double or FixedString (a fast wasty string class for
>>> strings up to a maximum size which inside has an "embedded" fixed array
>>> and an used field for shorter strings to be copied for the exact extent,
>>> they are asciiZ '\0' terminated for support of std functions)
>>
>> So, reinventing std::string. Why?
>
> no it's not : all stuff static or automatic, no malloc, no new operator,
> no throw and so. At the cost of waste of space (and negligible
> limitation due to natural fields size).

OK, I was somehow thinking you are trying to do short string optimization.
>
>>
>>>
>>>
>>> template <typename tt> class Table
>>> {
>>> tt Dati [constMaxRighe] [constMaxColonne];
>>>
>>> template <typename xx> Table <xx> ExtractSubTable \
>>> (int * SelectedRowList, int * SelectedColumnList, \
>>> int numRows, int numCols);
>>
>> What's this obsession with backslashes and line continuation? It's not
>> needed beyond macro definitions.
>
> how in the NG is to be reported line continuation ?
> Underscore ?

URL-s can be enclosed in <..> or "..". For other stuff it's not so
important to fit onto a single line. Large C++ statements naturally span
multiple lines, no backslash is needed. A semicolon typically marks the
end of the statement.


> I would not want a "variant-like" cell, with a further field holding its
> type .... but this is not completely excluded though. With a union it
> could be done limiting the waste.

If you need to check at run-time whether something is a double or a
string, then you need to have something present at run-time what you can
check. Sorry, this is the "further field holding its type", you just
cannot avoid that. You can have a single field for the whole table
though, if the table is guaranteed to be homogeneous.

> The selection is done intersecating a list of active columns and
> same-class rows. All selected columns are expected to hold numeric data.
> The Table <double> is generated from extraction, then calculations. Than
> back-exported in textual complete table for logging as text file report.
[...]
>
> no there is not any customer. I am just trying to "translate" a facility
> for personal use to C++, but not for performance reason. The SW has
> grown to a size I have difficulty maintaining in gambas. Always the same
> problem.
> C++ forces me to be more tidy, when I manage to understand well the
> synthax at least.

If you want to have simple program for better maintenance, then that's
one more argument for the simpler solution I proposed: step 1, extract
subtable; step 2, convert it into needed type. No need to do everything
at once.



Paavo Helde

unread,
Dec 8, 2019, 9:53:31 AM12/8/19
to
On further pondering, I have not seen anything so far which would
require the type of the table being unknown at compile time. So your
wish to represent the table in a single class regardless of the data
type does not seem reasonable.

If I were you, I would just use two separate classes, e.g.
std::vector<double> and std::vector<std::string>, maybe with some slight
wrappers for emulating 2D access, and be done with it.

Soviet_Mario

unread,
Dec 8, 2019, 1:47:37 PM12/8/19
to
I agree with you (I just thought it before) from the program
point of view. From the "writer" of the code, well, too
boring duplicate almost identical code with just a few
specific features.
I wanted the templating mechanism to do this for me, just that.

But I am now also reconsidering the variant-like "union"
unique cell type, able to hold both a double and a FixedString.
The fitting code would just reside in this base type of
building block, transparent for the container (which would
no longer be a template then, or maybe just to size the
table max_rows / max_columns

>
> If I were you, I would just use two separate classes, e.g.

well, but isn'it so boring to recode by hand two twin types ?

> std::vector<double> and std::vector<std::string>, maybe with
> some slight wrappers for emulating 2D access, and be done
> with it.
>


Paavo Helde

unread,
Dec 8, 2019, 2:01:08 PM12/8/19
to
On 8.12.2019 20:47, Soviet_Mario wrote:
> On 08/12/19 15:53, Paavo Helde wrote:
> I agree with you (I just thought it before) from the program point of
> view. From the "writer" of the code, well, too boring duplicate almost
> identical code with just a few specific features.
> I wanted the templating mechanism to do this for me, just that.

I said two classes, not two class templates. If it makes sense, by all
means, you can code both classes as a single template. When instantiated
with different types, they become two different classes though.

> But I am now also reconsidering the variant-like "union" unique cell
> type, able to hold both a double and a FixedString.
> The fitting code would just reside in this base type of building block,
> transparent for the container (which would no longer be a template then,
> or maybe just to size the table max_rows / max_columns
>
>>
>> If I were you, I would just use two separate classes, e.g.
>
> well, but isn'it so boring to recode by hand two twin types ?

std::vector is already coded, so there is nothing to get bored about.
0 new messages