Friday, June 12, 2015

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

Paul <pepstein5@gmail.com>: Jun 12 06:12AM -0700

I'm confused by the syntax below. Why is the syntax for this static_cast not
X x1;
X&& x2 = static_cast<X&&>(x1);
x2 has been cast to the type X&& so why does the syntax make it seem as though x2 is of type X after the cast?
 
Many thanks for your help.
 
Paul
 
 
CODE THAT CONFUSES ME IS BELOW
X x1;
X x2 = static_cast<X&&>(x1);
"Öö Tiib" <ootiib@hot.ee>: Jun 12 08:03AM -0700

On Friday, 12 June 2015 16:13:07 UTC+3, Paul wrote:
 
> CODE THAT CONFUSES ME IS BELOW
> X x1;
> X x2 = static_cast<X&&>(x1);
 
You take the 2 lines of code out of context of what it
illustrates so how we can know what its purpose is?
 
The second line that confuses you makes perfect sense,
but is usually written like that:
 
X x2 = std::move(x1);

That does same thing so perhaps it was some text
about move semantics.
Paul <pepstein5@gmail.com>: Jun 12 08:39AM -0700

On Friday, June 12, 2015 at 4:03:58 PM UTC+1, Öö Tiib wrote:
 
> X x2 = std::move(x1);
 
> That does same thing so perhaps it was some text
> about move semantics.
 
Yes, it was about move semantics. Here's a better way of rephrasing the question. The code below compiles but gives a runtime crash.
The way to fix this is to delete the && from std::vector<std::string> && tmp = ...
 
My question is why this fix is necessary. Why doesn't the code below do the swap? Thank you very much for your help.
 
Paul
 
void swap( std::vector<std::string> & x, std::vector<std::string> & y )
{
std::vector<std::string>&& tmp = static_cast<std::vector<std::string> &&>( x );
x = static_cast<std::vector<std::string> &&>( y );
y = static_cast<std::vector<std::string> &&>( tmp );
}
 
int main()
{
 
std::vector<std::string> vecStr1{"hello", "world"};
std::vector<std::string> vecStr2{"heh", "one"};
swap(vecStr1, vecStr2);
std::cout<<vecStr1[0];
}
Martin Shobe <martin.shobe@yahoo.com>: Jun 12 11:27AM -0500

On 6/12/2015 10:39 AM, Paul wrote:
> x = static_cast<std::vector<std::string> &&>( y );
> y = static_cast<std::vector<std::string> &&>( tmp );
> }
 
rvalue references are still references. tmp and x refer to the same
object. When you do the first assignment, the contents of y become the
contents of x and y becomes limited in what you can do with it until you
assign to it. When you do the second assignment, the contents of y
becomes the contents tmp (i.e. x) and tmp (x) becomes limited in what
you can do with it.
 
When you remove the &&, tmp becomes a copy of x, so the second move
limits tmp but not x.
 
Martin Shobe
Paavo Helde <myfirstname@osa.pri.ee>: Jun 12 12:08PM -0500

Paul <pepstein5@gmail.com> wrote in
> static_cast<std::vector<std::string> &&>( y ); y =
> static_cast<std::vector<std::string> &&>( tmp );
> }
 
For moving around vector contents you need an actual place to hold a
vector content meanwhile, having any number of references is not enough.
 
A car analogy: you have 2 stolen cars hidden in 2 trucks. You need to
swap these cars so that nobody can see a car. Each truck can hold 1 car
only, but you can manouver them so that a car can drive directly from one
truck into another (empty) truck. You have unlimited number of fake
license plates (references) for trucks and cars. How to solve?
 
Hint: moving license plates around does not solve the problem, you need
another (empty) truck.
 
hth
Paavo
ram@zedat.fu-berlin.de (Stefan Ram): Jun 11 11:50PM

>The std::array example that was posted earlier in this thread
>has that bug.
 
Yes. Thank you!
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 01:29AM

>Does it? Your 'get2' function takes its argument by what, value,
>pointer or reference? Proceed answering my first question after
>answering my second, please.
 
Thank you! I already admitted my mistake in
 
<bug-20150612015004@ram.dialup.fu-berlin.de>
 
. »by value« and »no«.
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 05:04PM

I found this:
 
int n = b ? (1, S::x) // S::x is not odr-used here
: f(S::x); // S::x is odr-used here, so
// a definition is required
 
In or near the example, the type or value of »b« was not
given.
 
I do not understand the »not«. The value of »,«
is its right operand. So »(1, S::x)« is effectively
»S::x«. Why does it say that »S::x« is /not/ odr-used?
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 05:06PM

For my tutorial, I want to write about implicitly defined
functions. By this I mean, functions of a class that can be
used, even if the programmer has not written definitions for
them.

So, I was curious, what functions /are/ implicitly defined.
I found this source code:
 
struct trivial {
trivial() = default;
trivial(const trivial&) = default;
trivial(trivial&&) = default;
trivial& operator=(const trivial&) = default;
trivial& operator=(trivial&&) = default;
~trivial() = default;
};
 
The accompanying notes did not say so: But I wonder whether it might
be possible that the above source code already lists /all/ the
functions that usually are implictly defined, e.g., in the case of
 
struct example {};
 
. So, do you deem the above list to be complete?
 
(For simplicity, I assume here, that all potentially
implicitly defined entries are odr-used, so that they
/really/ are defined.)
"K. Frank" <kfrank29.c@gmail.com>: Jun 11 10:01PM -0700

Hi Doug (and Ian)!
 
On Thursday, June 11, 2015 at 3:11:27 PM UTC-4, Ian Collins wrote:
> > Stroustrup book and do the work with a compiler that complements the
> > theory
 
> Install Cygwin and g++.
 
There is also mingw-w64. It is a fork of, and a separate project
from mingw (and, just to be clear, is a windows port of gcc). This
allows you to run g++ on windows without the potentially undesirable
overhead of cygwin. (But cygwin offers its own benefits, as well.)
 
Mingw-w64 offers g++ builds that support std::thread out of the
box. I have used mingw-w64 for almost all basic std::thread
features, and I haven't come across any problems.
 
(The most recent versions of g++ might enable c++11 / c++14 features
automatically, but until recently you had to include "-std=c++11"
(or "-std=gnu++11" or "-std=++14", etc.) on the command line for
std::thread (and other c++11 features) to work.
 
 
> Ian Collins
 
 
Good luck!
 
 
K. Frank
"Öö Tiib" <ootiib@hot.ee>: Jun 12 01:54AM -0700

On Thursday, 11 June 2015 22:11:27 UTC+3, Ian Collins wrote:
> > tutorialspoint.com online C++ shell for smaller activities. I was
> > thinking of getting Microsoft's VC++ lite, but I heard they don't
> > follow the C++11 standard on everything...I only heard that.
 
MSVC is fine in practice. MinGW also usually just works fine.
Likely it is some silly configuring problem.
 
> > Stroustrup book and do the work with a compiler that complements the
> > theory
 
> Install Cygwin and g++.
 
Cygwin is not simpler to configure than MinGW.
 
Cygwin emulates UNIX/POSIX more fully than MinGW but when we compile
under it then we get Cygwin app. That can be good enough for our own
purposes but more often we want to get Windows app to give to someone
else. Windows app we can get with MinGW or with MSVC but not with
Cygwin.
Luca Risolia <luca.risolia@linux-projects.org>: Jun 12 04:37PM +0200

On 11/06/2015 19:18, K. Frank wrote:
> available to all threads in your process. (There is
> such a thing as "thread-local storage," but you're
> not using it.)
 
1) and 2) are essentially wrong.
 
The thread constructor copies or moves all the arguments to
*thread-accessible storage*.
 
In this case, when f is invoked in the context of the new thread, "res"
is a *copy* of "res1" (they are distinct pointers pointing to the same
object).
Doug Mika <dougmmika@gmail.com>: Jun 12 08:34AM -0700

On Friday, June 12, 2015 at 9:37:47 AM UTC-5, Luca Risolia wrote:
 
> In this case, when f is invoked in the context of the new thread, "res"
> is a *copy* of "res1" (they are distinct pointers pointing to the same
> object).
 
How do we choose between the thread constructor "copying" or "moving" the arguments to "thread-accessible storage"? (I had a look at the thread constructors at www.cplusplus.com but I didn't manage to figure it out from that - actually, template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);, don't the && imply "moving" of the arguments as they are/expect rvalues?)
"K.Frank" <kfrank29.c@gmail.com>: Jun 12 09:27AM -0700

Hello Luca!
 
On Friday, June 12, 2015 at 10:37:47 AM UTC-4, Luca Risolia wrote:
 
> In this case, when f is invoked in the context of the new thread, "res"
> is a *copy* of "res1" (they are distinct pointers pointing to the same
> object).
 
No, I don't think your description of what is happening is
correct.
 
In short, res1 is a double, while res is a double*. A copy
of res1 is never made. res points to res1, in place on the
stack as a variable local to main.
 
In more detail, here's Doug's code from "main":
 
// ...
double res1;
double res2;
thread t1 {f,some_vec,&res1}; //f(some_vec,&res1) executes in a separate
//thread
thread t2 {F{vec2,&res2}}; // F{vec2,&res2}() executes in a separate
//thread
 
Please note that res1 and res2 are of type double. They
are not pointers to doubles. The t1's thread constructor
gets called with &res1, which is indeed a pointer-to-double,
and points to res1, a variable local to main, and on the stack.
(Basically the same thing happens with res2.)
 
The third argument of Doug's thread function f (res) is
a pointer-to-double, and when is gets called it does
indeed get called with a copy of the value of &res1,
but this value points to res1, the variable local to
main. A copy of res1 is never made. If res1 is accessed
by main or goes out of scope before the thread t1 modifies
it (through the pointer-to-double res that has the value
&res1), trouble arises. That is why some sort of
synchronization is needed (in Doug's example, t1.join()).
 
 
Good luck.
 
 
K. Frank
red floyd <no.spam@its.invalid>: Jun 12 09:47AM -0700

On 6/12/2015 1:54 AM, Öö Tiib wrote:
> purposes but more often we want to get Windows app to give to someone
> else. Windows app we can get with MinGW or with MSVC but not with
> Cygwin.
 
You can install MinGW compilers under Cygwin as well.
fl <rxjwg98@gmail.com>: Jun 12 08:53AM -0700

Hi,
 
I find the following code snippet on line as a tutorial for me. The first
'struct BaseConstructor' looks bizarre to me, as it does not look like a
general class/struct. Could you explain it to me?
 
 
 
Thanks,
 
 
 
 
 
 
//////////////////////////
struct BaseConstructor
{
BaseConstructor(int=0)
{}
};
 
class RealNumber;
class Complex;
class Number;
class Number
{
friend class RealNumber;
friend class Complex;
public:
Number ();
Number & operator = (const Number &n);
Number (const Number &n);
virtual ~Number();
virtual Number operator + (Number const &n) const;
void swap (Number &n) throw ();
 
static Number makeReal (double r);
static Number makeComplex (double rpart, double ipart);
protected:
Number (BaseConstructor);
 
private:
void redefine (Number *n);
virtual Number complexAdd (Number const &n) const;
virtual Number realAdd (Number const &n) const;
 
Number *rep;
short referenceCount;
};
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 12:45PM -0400

On 6/12/2015 11:53 AM, fl wrote:
> I find the following code snippet on line as a tutorial for me. The first
> 'struct BaseConstructor' looks bizarre to me, as it does not look like a
> general class/struct. Could you explain it to me?
 
Not enough information. We see that 'Number' uses it. But we don't see
in what situation it's going to be used. What we need is to see the
code in which the protected constructor of 'Number' (which takes an
instance of 'BaseConstructor' as its argument) is going to be used.
 
Most likely (if I were to speculate) that 'RealNumber' and 'Complex'
classes derive from 'Number' and hence they make use of that protected
constructor of 'Number' in their own constructor. But it's unclear how
they do it without seeing the definitions of their own c-tors.
 
 
> Number *rep;
> short referenceCount;
> };
 
V
--
I do not respond to top-posted replies, please don't ask
Doug Mika <dougmmika@gmail.com>: Jun 12 08:50AM -0700

So I am in the midst of reading Stroupstrup's book, The Programming Language 4th ed, and I came upon this little program to help us sort singly linked containers that do not provide random iterator access to the data. Basically, he writes an "adapter" (I hope I'm using the term correctly) to sort a singly linked list by copying the singly linked list into a vector, sorting the vector, and then copying back the vector into a singly linked list. The neat, and confusing part is some of the commands he uses, which I was hoping someone could explain:
 
void test(vector<string>& v, forward_list<int>& lst) {
sort(lst); //sort the singly linked list
}
 
He writes two helper functions that take an extra argument indicating whether the sort is to be used for singly-linked iterators or random iterators:
template<typename Ran> //for random access iterators
void sort_helper(Ran beg, Ran end, random_access_iterator_tag) //we can subscript into [beg:end)
{
sort(beg,end); //just sort it
}
 
and
 
template<typename For> //for forward iterators
void sort_helper(For beg, For end, forward_iterator_tag) //we can traverse [beg:end)
{
vector<decltype(*beg)> v {beg,end}; //initialize the vector
sort(v.begin(),v.end());
copy(v.begin(),v.end(),beg); //copy the elements back
}
 
QUESTION: I have never seen the paramters of a function be in the format "forward_iterator_tag", I have always only seen "Type instance" ie "int myInt". What is "forward_iterator_tag", and where is its type?
 
The selection of the helper function happens here:
template<typname C>
void sort(C& c) {
using Iter = Iterator_type<C>;
sort_helper(c.begin(),c.end(),Iterator_category<Iter>{});
}
 
QUESTION:
1)How would this sort template look if we were to not have using Iter = Iterator_type<C>;? What does this line do? - I have never seen it used in this context.
2)What is Iterator_type and Iterator_category? I searched for these on www.cplusplus.com but found nothing that would make it clear.
 
Thanks to all for reading something this long.
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 12:39PM -0400

On 6/12/2015 11:50 AM, Doug Mika wrote:
> 1)How would this sort template look if we were to not have using Iter = Iterator_type<C>;? What does this line do? - I have never seen it used in this context.
> 2)What is Iterator_type and Iterator_category? I searched for these on www.cplusplus.com but found nothing that would make it clear.
 
> Thanks to all for reading something this long.
 
'forward_iterator_tag' and 'random_access_iterator_tag' are the types
defined by the library. Those types are to what 'Iterator_category'
instantiations result into.
 
It's not all that difficult, really. 'Iterator_type<C>' makes 'Iter' to
be a particular type. Then it used as the argument to the
'Iterator_category' template. When you create an object of that
category, it creates an object of one of those '_tag' types. So, the
'sort_helper's third argument becomes either one type or the other, and
the compiler creates the code that calls either one 'sort_helper'
specialisation or the other (from the two which you/he defined).
 
When templates are concerned, start your tracing from the bottom.
Imagine yourself the compiler. Substitute 'sort(C& c)' with the call
made and try to understand what type is 'C' here. Now "process" the
body of that template function, with the specific 'C' in mind. The
'using' directive makes 'Iter' something particular. What is it? It's
something that arrives from 'Iterator_type' template. Take a look what
the 'Iterator_type' template gives when its argument is 'std::vector',
and what it gives when its argument is 'std::forward_list'.
 
And so on...
 
V
--
I do not respond to top-posted replies, please don't ask
Kalle Olavi Niemitalo <kon@iki.fi>: Jun 12 02:45AM +0300


> I suspect the author is thinking of something like
 
> const int& findMax(const std::vector<int>& vec)
 
To the OP: It is important to pass the vec parameter by
reference. If it were passed by value, then its elements would
be deallocated at the end of the function, and the returned
reference to one of the elements would become invalid, even
though the compiler probably would not notice the problem.
The std::array example that was posted earlier in this thread
has that bug.
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 11 09:05PM -0400

On 6/11/2015 5:54 PM, Stefan Ram wrote:
> ::std::cout << get2( a )<< '\n'; }
 
> The object a[ 2 ] has a lifetime that transcends
> the lifetime of get2( a ).
 
Does it? Your 'get2' function takes its argument by what, value,
pointer or reference? Proceed answering my first question after
answering my second, please.
 
V
--
I do not respond to top-posted replies, please don't ask
Rosario19 <Ros@invalid.invalid>: Jun 12 09:41AM +0200

On Thu, 11 Jun 2015 14:35:44 -0700 (PDT), Paul wrote:
 
 
> return max;
 
>}
 
>If we change the signature to return a reference, I understand perfectly that we get an error because we're returning a reference to the local variable max. But if we don't do that, what does the author have in mind?
 
i don't know too much in the few i know
i think something as:
 
int& findMax(std::vector<int> vec)
{static int max;
 
if(vec.empty())
throw std::runtime_error("Empty vector");
 
max = vec[0];
for(int i = 1; i < vec.size(); ++i)
if(vec[i] > max)
max = vec[i];
return max;

}
 
if it is need one more big obj it is enought one static obj
 
it is *not ok* when the function is used many thread at once togheter
or in case 1 thread as in (a+b) + (a+c)
 
[if "+" return a reference to a static object always the same without
use = to somenting other ]
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Jun 12 02:58AM -0600

On Fri, 12 Jun 2015 09:41:02 +0200, Rosario19 <Ros@invalid.invalid>
wrote:
 
>or in case 1 thread as in (a+b) + (a+c)
 
>[if "+" return a reference to a static object always the same without
>use = to somenting other ]
 
No. Don't do this. Ever.
 
Louis
Rosario19 <Ros@invalid.invalid>: Jun 12 11:53AM +0200

On Fri, 12 Jun 2015 02:58:15 -0600, Louis Krupp wrote:
 
>>use = to somenting other ]
 
>No. Don't do this. Ever.
 
>Louis
 
i'm not agree in your answer...
 
i agree in the my cousin answer :
"se non sbagli non impari ovvero se non commetti degli errori non puoi
correggerli"
 
"if you're not wrong you will not learn how you can correct mistakes"
 
i don't say i'm right...
"Öö Tiib" <ootiib@hot.ee>: Jun 12 05:10AM -0700

On Friday, 12 June 2015 10:41:14 UTC+3, Rosario19 wrote:
> or in case 1 thread as in (a+b) + (a+c)
 
> [if "+" return a reference to a static object always the same without
> use = to somenting other ]
 
There is generic standard algorithm for finding max element from range
of elements. It returns iterator (or pointer on case of raw array) to the
element:
 
int& element = *std::max_element( vec.begin(), vec.end() );
 
Why to write functions that attempt to do same thing in defective, less
efficient and/or constrained way?
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: