Wednesday, January 27, 2016

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

Daniel <danielaparker@gmail.com>: Jan 26 04:17PM -0800

One, in cppreference http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer it says that
 
"The following rules apply to object construction:
 
Copy constructors of AllocatorAwareContainers obtain their instances of the
allocator by calling
 
std::allocator_traits<allocator_type>::select_on_container_copy_construction
on the allocator of the container being copied.
 
Move constructors obtain their instances of allocators by move-constructing
from the allocator belonging to the old container.
 
All other constructors take an allocator parameter."
 
So regarding copy and move constructors, how does it fit in that since C++
11, the standard library container copy and move constructors also take an
allocator parameter? Can a container that does not provide those overrides
be considered allocator aware?
 
Two, also in cppreference, it says that
 
"An AllocatorAwareContainer is a Container that holds an instance of an
Allocator and uses that instance to allocate and deallocate memory in all of
its member functions."
 
So suppose we have a container which internally stores (say)
 
std::basic_string<char_type,std::char_traits<char_type>,some_allocator_type> name_,
 
but as a convenience to the user exposes it as
 
std::basic_string<char_type> name() const
{
return std::basic_string<char_type>(name_.data(),name_.length());
}
 
can such a container be legitimately called allocator aware?
 
Thanks,
Daniel
"Öö Tiib" <ootiib@hot.ee>: Jan 27 03:03AM -0800

On Wednesday, 27 January 2016 02:17:58 UTC+2, Daniel wrote:
> 11, the standard library container copy and move constructors also take an
> allocator parameter? Can a container that does not provide those overrides
> be considered allocator aware?
 
No.
 
> {
> return std::basic_string<char_type>(name_.data(),name_.length());
> }
 
Containers are objects used to store other objects and taking care of the
management of the memory used by such elements but that 'name' isn't
apparently meant as such contained element.
 
 
> can such a container be legitimately called allocator aware?
 
I think yes but I would generally expect classes with properties like 'name'
to have "has a" relation with container not "is a" relation. Otherwise the
class has different and unrelated responsibilities.
Daniel <danielaparker@gmail.com>: Jan 27 07:47AM -0800

On Wednesday, January 27, 2016 at 6:03:43 AM UTC-5, Öö Tiib wrote:
>> an allocator parameter? Can a container that does not provide those
>> overrides be considered allocator aware?
 
> No.
 
Thanks. It appears that after many years of having avoided it, I need to read the standard itself.
 
Daniel
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 05:20PM +0100

On 1/27/2016 1:17 AM, Daniel wrote:
 
> So regarding copy and move constructors, how does it fit in that since C++
> 11, the standard library container copy and move constructors also take an
> allocator parameter?
 
They don't.
 
A copy or move constructor /could/, in principle, take an allocator
parameter if it were defaulted, and still be a copy or move constructor,
because the requirement on a copy or move constructor's signature, just
as with a default constructor, is on how it can be called.
 
The text above describes how copy and move constructors for an allocator
aware container obtain allocator instances for the new instance: it's
not via a parameter.
 
 
> Can a container that does not provide those overrides
> be considered allocator aware?
 
Yes, there are no such constructors.
 
 
> return std::basic_string<char_type>(name_.data(),name_.length());
> }
 
> can such a container be legitimately called allocator aware?
 
Yes, if it provides a means to specify the allocator type. You can't
make the class less allocator aware by adding convenience methods.
Usually the allocator type is a defaulted template parameter.
 
All that said, I find the machinery described in the quoted text,
repulsive in a way. It's very kludgy. Unclean.
 
There are probably good historical reasons for it but ouch!
 
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 05:24PM +0100

On 1/27/2016 5:20 PM, Alf P. Steinbach wrote:
 
> The text above describes how copy and move constructors for an allocator
> aware container obtain allocator instances for the new instance: it's
> not via a parameter.
 
I meant, not /as/ a parameter, that there's no allocator parameter.
 
 
Cheers,
 
- Alf
Daniel <danielaparker@gmail.com>: Jan 27 08:53AM -0800

On Wednesday, January 27, 2016 at 11:20:53 AM UTC-5, Alf P. Steinbach wrote:
> > 11, the standard library container copy and move constructors also take an
> > allocator parameter?
 
> They don't.
 
They do :-)
 
> aware container obtain allocator instances for the new instance: it's
> not via a parameter.
> .
 
That text is incomplete.
 
Check Allocator-aware container requirements,
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf
Table 99.
 
Post it's require that get_allocator() == the passed allocator parameter, if one is provided.
 
Daniel
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 06:30PM +0100

On 1/27/2016 5:53 PM, Daniel wrote:
>>> allocator parameter?
 
>> They don't.
 
> They do :-)
 
Uhm, not sure how you arrive at that conclusion, so not sure what to
explain.
 
Regarding terminology, a "copy constructor" for class T is one that can
be called with a single argument of type T, where the formal argument
type is one 4 allowed by the standard. It's not enough that a
constructor copies a T instance. It must be callable with single arg.
 
And ditto for move constructor.
 
Let's consider a concrete example, std::vector.
 
C++11 §23.3.6.1 provides a class declaration, with the following
constructors that can be passed a std::vector as first argument:
 
 
vector(const vector<T,Allocator>& x);
vector(vector&&);
 
vector(const vector&, const Allocator&);
vector(vector&&, const Allocator&);
 
The first one is the copy constructor. It has /a single formal argument/
of vector type. The standard's requirement of a copy constructor for
class T is that it can be called with a single argument of type T. The
standard lists 4 possible formal argument types for that first argument,
and those include pass by ref to const, as above.
 
The second one is the move constructor.
 
The third and fourth have allocator arguments. They are neither copy nor
move constructors, because they do not conform to the requirements on a
copy or move constructor. They can't be called with single argument.
 
Summing up, AFAIK there are no copy or move constructors in the standard
library with allocator as extra argument.
 
If there were then, as I mentioned in the original response, the
allocator argument would have to be defaulted.
 
 
 
Cheers & hth.,
 
- Alf
Christopher Pisz <nospam@notanaddress.com>: Jan 26 05:25PM -0600

On 1/26/2016 1:08 PM, Bill Cunningham wrote:
> using std namespace;
 
> So I've never done anything with namespaces. Nor in C.
 
> Bill
 
Don't make a habit of auto typing using namespace std in every cpp file
without it actually running through your mind that "I intend to lookup
these names in the std namespace". One day you'll run into a case where
you don't want to and are actually after something else.
 
 
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Juha Nieminen <nospam@thanks.invalid>: Jan 27 10:56AM

> I've done before I have...
 
> #include <iostream>
> using std namespace;
 
What benefit do you get by doing that?
 
(And no, avoiding the "std::" prefix is not a benefit. I could write a
lengthy essay on why.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
JiiPee <no@notvalid.com>: Jan 27 12:52PM

On 27/01/2016 10:56, Juha Nieminen wrote:
 
> (And no, avoiding the "std::" prefix is not a benefit. I could write a
> lengthy essay on why.)
 
> --- news://freenews.netfront.net/ - complaints: news@netfront.net ---
 
but you agree, its faster and shorter though? (varmasti olet samaa
mielta etta on lyhyaempi? :) )
like when teaching, less confusion maybe?
JiiPee <no@notvalid.com>: Jan 27 12:55PM

On 26/01/2016 19:57, Paavo Helde wrote:
> buff[0] = 1;
> buff[100000] = 2;
 
> Note that here the 'buff' container contains 2 elements (not 100001).
 
somebody said in a conference video , concpp 2014, that map is bad and
should not be used. performance issues... donno....
"Bill Cunningham" <nospam@nspam.invalid>: Jan 27 09:08AM -0500

"Juha Nieminen" <nospam@thanks.invalid> wrote in message
news:n8a7p1$k7f$1@adenine.netfront.net...
 
> What benefit do you get by doing that?
 
> (And no, avoiding the "std::" prefix is not a benefit. I could write a
> lengthy essay on why.)
 
Well I'm not dealing with different namespaces. I never have. If your going
to do that, the scoping operator with std namespace would be a good habit. I
want to learn the standard namespace.
 
Bill
"Bill Cunningham" <nospam@nspam.invalid>: Jan 27 09:10AM -0500

"Vir Campestris" <vir.campestris@invalid.invalid> wrote in message
news:0a6dnRcwOoElYzrLnZ2dnUU78U-dnZ2d@brightview.co.uk...
 
> What nobody has mentioned is that malloc must have a matching free. And it
> must be there on _all_ the error paths.
 
Yes indeed.
 
> Whereas with the C++ methods you just create your vector, and when it goes
> out of scope the language cleans it up for you.
 
How does it do that?
 
Bill
JiiPee <no@notvalid.com>: Jan 27 02:27PM

On 27/01/2016 14:08, Bill Cunningham wrote:
> Well I'm not dealing with different namespaces. I never have. If your going
> to do that, the scoping operator with std namespace would be a good habit. I
> want to learn the standard namespace.
 
I guess the issue is that even if you do not use now, you might use it
later on in the same project. So they are there ready.
Paavo Helde <myfirstname@osa.pri.ee>: Jan 27 04:58PM +0200

On 27.01.2016 14:55, JiiPee wrote:
 
> somebody said in a conference video , concpp 2014, that map is bad and
> should not be used. performance issues... donno....
 
If you need the functionality of std::map, then I am sure std::map is as
good as it gets. If you don't need this functionality, then you use
something else, like std::vector or std::unordered_map().
 
In any case, premature optimization is the root of all the evil as we
know, first get the code correct and clear, then if the performance is
not good, profile and fix the problems. Without working code you even
cannot know where the bottlenecks are, and if the code is not clear it
would be very difficult to add the needed optimizations.
 
Cheers
Paavo
Victor Bazarov <v.bazarov@comcast.invalid>: Jan 27 10:00AM -0500

On 1/27/2016 9:10 AM, Bill Cunningham wrote:
 
>> Whereas with the C++ methods you just create your vector, and when it goes
>> out of scope the language cleans it up for you.
 
> How does it do that?
 
When the automatic object of type std::vector<...> goes out of scope,
the d-tor is called, and *in it* the dynamic memory (if any) is freed.
 
V
--
I do not respond to top-posted replies, please don't ask
Paavo Helde <myfirstname@osa.pri.ee>: Jan 27 05:01PM +0200

On 27.01.2016 16:10, Bill Cunningham wrote:
 
>> Whereas with the C++ methods you just create your vector, and when it goes
>> out of scope the language cleans it up for you.
 
> How does it do that?
 
RAII (https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization).
 
One of the most important strengths of C++, IMO.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 27 01:08AM

On Mon, 2016-01-25, David Brown wrote:
> On 25/01/16 15:21, Jorgen Grahn wrote:
>> On Mon, 2016-01-25, Juha Nieminen wrote:
...
>> a real type behind the 'auto' -- the only issue is if the reader gets enough
>> useful information about it, without seeing it spelled out.
 
> Python also has strong typing.
 
Yes; I'm probably talking about "static typing", and maybe that was
what Juha N. wanted to say, too.
 
[snip description]
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
David Brown <david.brown@hesbynett.no>: Jan 27 08:54AM +0100

On 27/01/16 02:08, Jorgen Grahn wrote:
 
>> Python also has strong typing.
 
> Yes; I'm probably talking about "static typing", and maybe that was
> what Juha N. wanted to say, too.
 
That makes more sense, at least regarding Python. But "auto" in C++ is
still static typing - it is just not necessarily explicit typing. If
you write "auto x = 123;", then "x" is statically typed as an "int" -
you can't assign a pointer or a string to it. And the static type used
for the "auto" variable comes directly from its initialiser - if the
initialiser's type is clear, then the type of the "auto" variable is
equally clear without the programmer having to duplicate the same
information.
 
So "auto" is not really circumventing either the strong typing system,
or the static typing system - it is merely reducing the verbosity of the
code. Clearly you can't use "auto" in cases where you don't have the
initialiser (or function definition) on hand, such as for exported data
or class definitions - but in most cases where you /can/ use auto, it
does a fine job without losing any of the strengths of C++.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 02:12AM +0100

Following a suggestion from David Brown I've looked at how to make my
simple `is_ascii` function `constexpr`, for C++11.
 
At first I coded it as simple tail-recursive, but this had the problem
that without optimization it could blow the machine stack when it was
applied to a long string. So I now changed it to divide-and-conquer
recursive, buying safety at the cost of potential inefficiency in the
case where the arguments don't allow compile time evaluation. I gave
this function a new name, `constexpr_is_ascii`, so that one can choose:
efficient compile time evaluation when one knows the arguments allow
that, or reasonably efficient checking for data known only at run time.
 
Is there any way to /automate/ that choice?
 
• • •
 
For completeness & context, the relevant code:
 
constexpr
inline auto is_ascii( In_<char> code )
-> bool
{ return Byte( code ) <= Byte( Ascii::del ); }
 
template< class Iter >
auto is_ascii( In_value_<Iter> first, In_value_<Iter> after )
-> bool
{
for( Iter it = first; it != after; ++it )
{
if( not is_ascii( *it ) ) { return false; }
}
return true;
}
 
// If this isn't optimized in a smart way then it can be
inefficient when the
// arguments don't allow compile time evaluation. In that case:
stack depth
// O(log2 n), number of calls O(n). The iterator must be random access.
template< class Iter >
constexpr
auto constexpr_is_ascii( In_value_<Iter> first, In_value_<Size> n )
-> bool
{
return( 0?0
: n == 0?
true
: n == 1?
is_ascii( *first )
: //else
constexpr_is_ascii( first, n/2 ) and
constexpr_is_ascii( first + n/2, n - n/2 )
);
}
 
// See comment above ↑.
template< class Iter >
constexpr
auto constexpr_is_ascii( In_value_<Iter> first, In_value_<Iter> after )
-> bool
{ return constexpr_is_ascii( first, after - first ); }
 
 
Cheers,
 
- Alf
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jan 27 07:14AM +0100

n 27.01.16 02.12, Alf P. Steinbach wrote:
> Following a suggestion from David Brown I've looked at how to make my
> simple `is_ascii` function `constexpr`, for C++11.
 
[...]
Well, your problem is C++11.
 
So either you have the option to use your implementation for C++11 and
ensure that the optimizer catches your code on your target platform(s)
or you rely on extensions that some compilers provide regarding constexpr.
Basically you are looking forward to C++14 which allows the trivial
implementation of is_ascii(string) as constexpr. This could be
distinguished by #if.
 
[two implementations]
> Is there any way to /automate/ that choice?
 
So you want to overload your function with and without constexpr?
AFAIK this is not possible.
 
 
Marcel
Geoff <geoff@invalid.invalid>: Jan 26 04:14PM -0800

On Tue, 26 Jan 2016 09:51:00 -0500, Jerry Stuckle
 
>I was using the servers which eventually resulted in the RFPs
>for NNTP being created.
 
They're called RFCs and you're full of BS.
Jerry Stuckle <jstucklex@attglobal.net>: Jan 26 08:28PM -0500

On 1/26/2016 7:14 PM, Geoff wrote:
 
>> I was using the servers which eventually resulted in the RFPs
>> for NNTP being created.
 
> They're called RFCs and you're full of BS.
 
Sorry, - I've been looking at RFP's for the last few days (mainly U.S.
Federal Government). I mixed up the terms. It doesn't mean I don't
know what I'm talking about.
 
But your head is so far up your ass you can see your tonsils.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
woodbrian77@gmail.com: Jan 26 03:55PM -0800

On Tuesday, January 26, 2016 at 2:40:30 PM UTC-6, Alf P. Steinbach wrote:
 
> - Alf
 
> Notes:
> [1] In <url: https://isocpp.org/wiki/faq/newbie#newbie-more-info>.
 
 
I'm willing to host the FAQ.
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 01:49AM +0100


>> Notes:
>> [1] In <url: https://isocpp.org/wiki/faq/newbie#newbie-more-info>.
 
> I'm willing to host the FAQ.
 
Thank you, but the hosting issue was about my tutorial, where first its
hosting in Norway (the Start homepage site run by newspaper Dagbladet)
and then its free hosting abroad, were unexpectedly discontinued. :( The
FAQ now has a fine new home at isocpp.org, with some expert contributors
including Andrei Alexandrescu, Herb Sutter and Bjarne Stroustrup (I
don't know about maintainance). The tutorial, is dead. :)
 
 
Cheers,
 
- Alf
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: