Tuesday, May 3, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 4 topics

"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: May 03 08:57AM +0200

Hi,
 
is it possible to store a type in a member variable and to use it again
for a template function?
 
class c_Area{
public:
template <typename t>
t* Area_T(t *vT){
static t *nT;
if(vT == NULL){
return nT;
} else {
nT = vT;
return nT;
}
}
 
std::string Name;
std::string Type;
};
 
 
Init:
nArea.Area_T < t > (nT);
 
Ask:
c_Area nArea;
cout << nArea.Area_T < ??? > (NULL)->Name();
 
'???' -> sure I know, what type is stored in Area_T, but is it maybe
possible to store the type of Area_T in c_Area so that I can use it
again for e.g. 'Ask'?
 
E.g.:
c_Area nArea;
cout << nArea.Area_T < nArea.TemplateType > (NULL)->Name();
 
Instead of:
c_Area nArea;
if(nArea.Type == "that_type")
cout << nArea.Area_T < that_type > (NULL)->Name();
 
Regards
Heinz-Mario Frühbeis
"Öö Tiib" <ootiib@hot.ee>: May 03 02:54AM -0700

On Tuesday, 3 May 2016 09:57:20 UTC+3, Heinz-Mario Frühbeis wrote:
> Hi,
 
> is it possible to store a type in a member variable and to use it again
> for a template function?
 
All types given as template argument must be compile-time known to
compiler in C++. For rum-time polymorphism there are base classes
and virtual member functions.
legalize+jeeves@mail.xmission.com (Richard): May 03 10:22PM

[Please do not mail me a copy of your followup]
 
=?UTF-8?Q?Heinz-Mario_Fr=c3=bchbeis?= <Div@Earlybite.individcore.de> spake the secret code
 
>is it possible to store a type in a member variable and to use it again
>for a template function?
 
Can you explain more the use case of why you would need to do this?
 
More generally, please describe the goal you are trying to achieve and
why you think this specific task is the way to achieve it.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Paavo Helde <myfirstname@osa.pri.ee>: May 03 09:32PM +0300

On 3.05.2016 20:26, Rick C. Hodgin wrote:
>> pass or use the reference.
 
> I WANT to use special syntax to pass by reference. I want it to show up
> in source code so I know it's a reference rather than a value pass.
 
Most class type objects are passed by reference. What you actually want
to show up in the source is pass by non-const reference.
 
What you can do is something like:
 
#include <iostream>
 
template<typename T>
class byref {
public:
T& ref;
operator T& () {
return ref;
}
explicit byref(T& ref): ref(ref) {}
};
 
template<typename T>
byref<T> ref(T& x) {
return byref<T>(x);
}
 
void some_function( byref<int> x) {
++x;
}
 
int main() {
 
int y = 1;
some_function(ref(y));
std::cout << y << "\n";
}
 
A believe a semi-decent compiler should be able to optimize the
templates away so there would be no runtime penalties.
 
hth
Paavo
Gareth Owen <gwowen@gmail.com>: May 03 08:28PM +0100


> I think that is a weak advantage for the additional syntactic
> complexity that he proposes.
 
I think it's a good argument - at least for references vs. naked
pointers. Tony Hoare didn't call null references a "billion dollar
mistake" lightly.
 
But ... the present reference syntax prevents null references (except by
deliberately lying to the compiler) already.
 
I see a good case for insisting pass-by-non-const-reference have a
little syntactic twist. That really does aid understanding,
particularly if your function names don't help.
 
Matrix m = { ... };
 
// does this modify m in place? Better check the docs.
vector<double> lambda = eigensystem(m);
 
// Oh, I remember, m contains the eigenvectors when we're done
vector<double> lambda = eigensystem(@m);
 
> In any event, Stroustrup presumably did.
 
So it would seem.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 12:30PM -0700

On Tuesday, May 3, 2016 at 3:17:02 PM UTC-4, Rick C. Hodgin wrote:
> > void some_function(int* x, int* y, int* z)
 
> > ?
 
> In important ways related to use:
 
If the values were updated:
 
> {
> // Use immediately with cleaner syntax
> other_thing(x + y + z);
x = 12;
y = 13;
z = 14;
> }
 
If the values were not updated:
 
some_function(x, y, z);
 
void some_function(const int& x, const int& y, const int& z)
{
// Use immediately with cleaner syntax
other_thing(x + y + z);
}
 
In this case, the fact that there is no @ doesn't matter because they
aren't updated. Only in the case of the non-const reference which
could potentially result in a value change would the @ be required.
 
This has been an evolution in my thinking throughout this post, though
I do not see any reason why the @ couldn't always be used to signify
that it is a pass-by-ref usage, rather than something else.
 
> {
> // Make sure pointers aren't NULL
> if (x && y && z)
{
> other_thing(*x + *y + *z);
*x = 12;
*y = 13;
*z = 14;
}
> }
 
In additional usage as well.
 
Best regards,
Rick C. Hodgin
"Öö Tiib" <ootiib@hot.ee>: May 03 12:33PM -0700

On Tuesday, 3 May 2016 21:50:23 UTC+3, Rick C. Hodgin wrote:
 
> What's wrong with:
 
> void some_function(int& x) {
> ++x;
 
Error here: 'x' is passing to inbuilt operator++ just by value in your
theory so it should be '++@x;'.
 
> }
 
> ??
 
> Why the need for the additional complexity?
 
Would it be simpler to write '++@x;' instead of '++x'? Also it would
lose all backward compatibility with C.
 
 
> -----
> Anyway, my question was, "What was their thinking?" and I think I see
> what it is now. I just happen to disagree with it.
 
In C++ we typically pass arguments by reference to const or by reference
or by r-value reference. Perhaps it would reduce the confusion if passing
by value had a special syntax but that is also missing because of backward
compatibility with C.
Gareth Owen <gwowen@gmail.com>: May 03 08:37PM +0100


> In this case, the fact that there is no @ doesn't matter because they
> aren't updated. Only in the case of the non-const reference which
> could potentially result in a value change would the @ be required.
 
I think that's a really good idea -- but I think you'll struggle to get
it adopted formally.
 
> This has been an evolution ...
 
Must ... resist ... cheap ... intelligent ... design ... joke ... :)
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 12:40PM -0700

On Tuesday, May 3, 2016 at 3:33:25 PM UTC-4, Öö Tiib wrote:
> or by r-value reference. Perhaps it would reduce the confusion if passing
> by value had a special syntax but that is also missing because of backward
> compatibility with C.
 
I was not aware C compilers allowed pass-by-ref syntax without some unique
compiler extensions / allowances being used. I thought they were a new
creation provided for by C++.
 
Best regards,
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 12:43PM -0700

On Tuesday, May 3, 2016 at 3:33:25 PM UTC-4, Öö Tiib wrote:
> > ++x;
 
> Error here: 'x' is passing to inbuilt operator++ just by value in your
> theory so it should be '++@x;'.
 
No. Usage within the function would be normal syntax. However, if you
wanted to pass it again by reference, then you could use @x. Otherwise
it would be driven by the called function.
 
Best regards,
Rick C. Hodgin
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 03 08:43PM +0100

On Tue, 03 May 2016 20:28:38 +0100
 
> I see a good case for insisting pass-by-non-const-reference have a
> little syntactic twist. That really does aid understanding,
> particularly if your function names don't help.
 
A little, but in an era of multiple processors not much. You may still
need to know whether an object is passed by reference to const or by
value for other reasons. If passed by reference to const, you know that
the receiving function will not mutate the object in the absence of an
obnoxious sleight of hand, but there is nothing to say another thread
with a non-const reference to the same object may not do so. So it
does not give an answer to such things as whether locking on reads is
required.
 
I don't think the gain is worth the additional syntax. Reasonable
people can disagree (you do). For sure though, the language
specification on this is not going to change.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 12:47PM -0700

On Tuesday, May 3, 2016 at 3:44:04 PM UTC-4, Chris Vine wrote:
> with a non-const reference to the same object may not do so. So it
> does not give an answer to such things as whether locking on reads is
> required.
 
That's a systemic issue though, and not a language issue.
 
> I don't think the gain is worth the additional syntax. Reasonable
> people can disagree (you do). For sure though, the language
> specification on this is not going to change.
 
:-) I've found that to be the case reliably in the comp.std.c group
as well (with a proposal to remove the requirement of having forward
declarations, as I wanted the compiler to go ahead and ignore the
first pass errors, and continue on looking for the missing declaration
or definition for use, provided it exists _somewhere_ in the source
code, so as to greatly simplify header ordering, and to even potentially
remove the need for header files by allowing the compiler to pre-parse
the raw source files and extract out relevant header information and
maintain that data persistently between compiles, refreshing it as
needed with some type of MAKE-like change comparison feature which would
kick off the recompile).
 
Best regards,
Rick C. Hodgin
Bo Persson <bop@gmb.dk>: May 03 09:49PM +0200

On 2016-05-03 21:11, Gareth Owen wrote:
 
> some_function(&x, &y, &z);
> void some_function(int* x, int* y, int* z)
 
> ?
 
And we still have the problem that with
 
int *x, *y, *z;
 
we call the function as
 
some_function(x, y, x);
 
 
How do we know what values might be modified?
 
Why is there no special syntax for this? :-)
 
 
 
Bo Persson
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 12:56PM -0700

On Tuesday, May 3, 2016 at 3:50:07 PM UTC-4, Bo Persson wrote:
 
> How do we know what values might be modified?
 
> Why is there no special syntax for this? :-)
 
> Bo Persson
 
Well, I think when we use pointers we already expect them to be updated.
But you're right, that's not always the case.
 
You bring up an interesting point. There's no reason why the @ syntax
couldn't be used there to indicate that it is a non-const usage, and could,
therefore, be updated.
 
some_function(@x, y, @x);
 
We know in this case x's members could be updated, but y won't. The
compiler could enforce usage of @ in the case of non-const usages, and
allow non-@ usages in the case of const usages.
 
-----
It's an interesting idea, but perhaps there could be another syntax to
signify a non-const usage exists as I think that would be good information
to know visually, rather than via a quick research effort.
 
Good question. I'll have to give it some thought.
 
Best regards,
Rick C. Hodgin
scott@slp53.sl.home (Scott Lurndal): May 03 08:01PM

>> in source code so I know it's a reference rather than a value pass.
 
>Most class type objects are passed by reference. What you actually want
>to show up in the source is pass by non-const reference.
 
With your coding style, that may, perhaps, be true.
 
That's not universally true by any means.
Gareth Owen <gwowen@gmail.com>: May 03 09:19PM +0100

> couldn't be used there to indicate that it is a non-const usage, and could,
> therefore, be updated.
 
> some_function(@x, y, @x);
 
Ah, but what if the arguments are reference-to-pointer?
 
void some_function(int*&,int*&,int*&);
 
Elephants ... all the way down.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 01:22PM -0700

On Tuesday, May 3, 2016 at 4:19:18 PM UTC-4, gwowen wrote:
 
> Ah, but what if the arguments are reference-to-pointer?
 
> void some_function(int*&,int*&,int*&);
 
> Elephants ... all the way down.
 
The general idea would be to ultimately look at the left-most form.
If it's not preceded with "const" then you'd need the @. :-)
 
Or, the opposite could be true, such that if it is a const it needs
some specific syntax. Both of those could be based on compiler
settings.
 
My primary concerns right now are in the silent pass-by-ref usgages
in syntax. I think they could all use the @ prefix to indicate they
are in use. However, I would also support an extension which would
then enforce additional syntax for non-const (or const) references,
so they are visibly cued in source code.
 
Best regards,
Rick C. Hodgin
Paavo Helde <myfirstname@osa.pri.ee>: May 03 11:28PM +0300

On 3.05.2016 21:57, K. Frank wrote:
> those arguments. (This is what I generally do. I either
> "forbid" the use of null -- and other invalid -- pointers,
> or test for them.)
 
Anything not expressed in the language can be encoded in the Hungarian
notation ;-) So that's what I have occasionally used for non-const
references:
 
void some_function(const int& x, int& y_out, int& z_inout) {
y_out = x + 1;
z_inout++;
}
 
I agree this is a bit ugly, but better than pointers (in my eye).
Non-const references should be avoided in general anyway. What's wrong
with packing the data in a class and using member functions instead?
 
Cheers
Paavo
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 01:29PM -0700

On Tuesday, May 3, 2016 at 4:22:59 PM UTC-4, Rick C. Hodgin wrote:
> are in use. However, I would also support an extension which would
> then enforce additional syntax for non-const (or const) references,
> so they are visibly cued in source code.
 
I would like to add one more thought to this ... I believe the future of
software development is moving toward the GUI, and because the cost of
machine resources is decreasing so rapidly, it is an absolute given that
the close and intimate nature of the editor+gui+compiler relationship will
be such that any decent EGC combination would be able to signal all of
this for your visually without requiring actual source code markup.
 
It is one of the avenues I am moving toward in my design. That being said,
I still believe there should be some cue in source code, be it artificially
injected by the EGC, or manually injected by the developer.
 
Best regards,
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 01:59PM -0700

On Tuesday, May 3, 2016 at 3:56:14 PM UTC-4, Rick C. Hodgin wrote:
> signify a non-const usage exists as I think that would be good information
> to know visually, rather than via a quick research effort.
 
> Good question. I'll have to give it some thought.
 
I like the idea of using @var for references. And I think there could
be designates for const or non-conts usage, which could signal the compiler
to generate warnings on improper use.
 
I think use of the ' symbol after the variable name, which would be kind
of like what we see in math with a, a', a'', etc.
 
We could also use the ! symbol after the variable name, which would be
an indicator that it is not being changed.
 
Example:
 
// Signal by-ref usage:
some_function(@x, @y, @z);
 
// Signal by-ref usage, with non-const on x using ':
some_function(@x', @y, @z);
 
// We could also explicitly signal by-ref const usage using !:
some_function(@x', @y!, @z!);
 
In this case, we know by visual inspection that x, y, and z are all
passed by reference. We know also that x is non-const and could be
updated. We know that y and z are const and won't be updated.
 
I'm also open to other syntax suggestions. I don't know where either
of those would interfere with anything, and if/where they would, a
simple whitespace would be enough to delineate.
 
Best regards,
Rick C. Hodgin
Ian Collins <ian-news@hotmail.com>: May 04 10:20AM +1200

On 05/04/16 08:59, Rick C. Hodgin wrote:
 
> I like the idea of using @var for references. And I think there could
> be designates for const or non-conts usage, which could signal the compiler
> to generate warnings on improper use.
 
The compiler already will generate warnings on improper use.
 
Non-const reference parameters are comparatively rare in C++ code, most
reference parameters are const which are all be indistinguishable from
pass by value to the caller, so no special notation is needed or desirable.
 
As others have said, sensible function naming should be used along with
non-const reference parameters. If you really want to be explicit,
there already is a special syntax - pass by pointer!
 
--
Ian Collins
Gareth Owen <gwowen@gmail.com>: May 03 07:57PM +0100


>> Show where it violates the C standard.
 
> I can see that you are a fan of pantomime.
 
Oh no. He isn't.
legalize+jeeves@mail.xmission.com (Richard): May 03 10:18PM

[Please do not mail me a copy of your followup]
 
Sounds like we used a lot of the same stuff around the same time.
There's something to be said for gaining experience in a richly
heterogeneous environment that broadens your perspective on things.
 
If you've only ever used Windows or Linux, I recommend using something
radically different like a LISP machine or PLATO. Even if it is only
through an emulator, it will broaden your perspective on how to
interact with the machine.
 
slp53@pacbell.net spake the secret code
 
>legalize+jeeves@mail.xmission.com (Richard) writes:
>>- CDC Cyber running PLATO
 
>Yep. DnD, Empire and Notes!
 
You might find my blog post on the PLATO @ 50 conference interesting:
<https://legalizeadulthood.wordpress.com/2010/06/28/plato50-conference/>
<https://legalizeadulthood.wordpress.com/2010/06/24/plato50-conference-video/>
 
>fellow in Tasmania who is developing a B6700 simulator.
 
>http://www.retrocomputingtasmania.com/home/projects/burroughs-b6700-mainframe
>(with fond memories of the TD-830's in the foreground).
 
Neat!
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
ram@zedat.fu-berlin.de (Stefan Ram): May 03 01:29PM

>is it possible to store a type in a member variable and to use it again
>for a template function?
 
No, but one can write the following.
 
#include <iostream>
#include <ostream>
#include <typeinfo>
 
struct clazz { using membervariable = int; };
 
template< typename T >void f()
{ ::std::cout << typeid( T ).name() << '\n'; }
 
int main() { f< clazz::membervariable >(); }
ram@zedat.fu-berlin.de (Stefan Ram): May 03 09:51PM

>we call the function as
>some_function(x, y, x);
>How do we know what values might be modified?
 
In
 
void example( int * x ) { f( x ); }
 
, we can't even exclude that f might modify x,
because it just might be
 
void f( int * & x ){ x = nullptr; }
 
for example.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: