Sunday, June 12, 2016

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

James Moe <jimoeDESPAM@sohnen-moe.com>: Jun 12 12:47PM -0700

gcc 4.7.3
 
std::string UtilsSetPathSep2 (std::string & str, const char *
path_sep_char_new)
{ ... }
 
When passing the argument "str" by reference, "std::string &", this
error is emitted:
 
pmmsend.c: In function 'pmmsend_return_code_t program_args(int, char**,
prog_args_t&)':
pmmsend.c:449:63: error: invalid initialization of reference of type
'std::string& {aka std::basic_string<char>&}' from expression of type
'char*'
pmmsend.c:287:8: error: in passing argument 1 of 'std::string
UtilsSetPathSep2(std::string&, const char*)'
 
When "std::string &" is changed to "std::string", no error(s) result.
 
Is it not possible to use std::string by reference?
 
--
James Moe
jmm-list at sohnen-moe dot com
Ian Collins <ian-news@hotmail.com>: Jun 13 07:57AM +1200

On 06/13/16 07:47 AM, James Moe wrote:
> UtilsSetPathSep2(std::string&, const char*)'
 
> When "std::string &" is changed to "std::string", no error(s) result.
 
> Is it not possible to use std::string by reference?
 
Yes, but in this case you are passing a char* which will create a
temporary string. You can't bind a temporary object to a reference, so
you will have to use const std::string&, std::string or std::string&& as
the parameter type in this case.
 
--
Ian
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 13 01:29AM +0200

On 12.06.2016 21:47, James Moe wrote:
> pmmsend.c:449:63: error: invalid initialization of reference of type
> 'std::string& {aka std::basic_string<char>&}' from expression of type
> 'char*'
 
This means that you have tried to use a `char*` or a `char` array as
actual argument for the `std::string&` formal argument.
 
Since `std::string&` is a reference-to-non-`const`, where the function
can /modify/ the actual argument object, you need an actual argument of
the exact same type or a class derived from that type (in the latter
case the reference is bound to the `std::string` base class sub-object).
 
The function can't very well modify an instance of some other type as if
it were a `std::string`.
 
 
> pmmsend.c:287:8: error: in passing argument 1 of 'std::string
> UtilsSetPathSep2(std::string&, const char*)'
 
> When "std::string &" is changed to "std::string", no error(s) result.
 
Because now the argument is passed by value, which means that the actual
argument is copied or converted, or the behavior is /as if/ there is a
copying or conversion.
 
And `std::string` provides a constructor that accepts a `char const*`.
I.e. you get an automatic conversion.
 
The function's code now operates on a copy or an instance resulting from
a conversion, and so it can't affect the original argument, in your
specific case the `char` array.
 
 
> Is it not possible to use std::string by reference?
 
That's possible.
 
Since the function /returns/ a `std::string` you probably wanted
`std::string const&` anyway. :-)
 
 
Cheers & hth.,
 
- Alf
Paul <pepstein5@gmail.com>: Jun 12 04:02AM -0700

I don't seem to understand operators on vectors. I thought that you could write someVec == {} as a statement saying that someVec is empty.
 
However, this doesn't compile and I don't know why.
My error message is "expected primary-expression before '{' token".
I'd be grateful if someone could enlighten me. The complete code is below.
Thanks again for your help.
 
Paul
 
#include <vector>
 
int main()
{
std::vector<int> z;
if(z == {})
; // empty statement.
}
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 08:34AM -0400

On 6/12/2016 7:02 AM, Paul wrote:
> if(z == {})
> ; // empty statement.
> }
 
There is no operator== declared for std::vector. Equality operators are
not compiler-defined for user-defined classes. The library classes like
containers, streams, algorithms, etc. are user-defined from the language
point of view. Some of them (like std::string) do define operators like
== (as members or stand-alone functions). Most do not. You can find
more information on the available functionality if you just RTFM.
 
V
--
I do not respond to top-posted replies, please don't ask
Bonita Montero <Bonita.Montero@gmail.com>: Jun 12 03:06PM +0200

Am 12.06.2016 um 14:34 schrieb Victor Bazarov:
 
> There is no operator== declared for std::vector. ...
 
http://www.cplusplus.com/reference/vector/vector/operators/
 
--
http://facebook.com/bonita.montero/
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 03:24PM +0200

* On 12.06.2016 14:34, Victor Bazarov wrote:
> containers, streams, algorithms, etc. are user-defined from the language
> point of view. Some of them (like std::string) do define operators like
> == (as members or stand-alone functions). Most do not.
 
Adding to that...
 
With all standard containers (unless I'm mistaken, in which case, with
most all standard containers) you can use the misleadingly named member
function `empty` to check whether it's empty. Contrary to what the name
indicates, it does not empty the collection. It just checks.
 
std::bitset is not technically a container and has a differently named
empty checker, a method called `none`.
 
To get more readable code you can define an `is_empty` function for
vectors, like this:
 
template< class Item >
auto is_empty( std::vector<Item> const& v )
-> bool
{ return v.empty(); }
 
and then you can write more clearly
 
if( is_empty( z ) ) { ...
 
Defining such a wrapper for each container type of interest is some work
though. But defining a single general more smart wrapper that determines
if there is a boolean `empty` method and if so, uses it, is even more
work. I'm not posting my code for that, it would simply be too long, but
if you're interested you can look at it ¹at GitHub.
 
Cheers & hth.,
 
- Alf
 
Links:
¹
https://github.com/alf-p-steinbach/cppx/blob/master/source_code/cppx/core_language_support/sizes_and_lengths.hpp
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 03:34PM +0200

On 12.06.2016 15:06, Bonita Montero wrote:
> Am 12.06.2016 um 14:34 schrieb Victor Bazarov:
 
>> There is no operator== declared for std::vector. ...
 
> http://www.cplusplus.com/reference/vector/vector/operators/
 
Victor jumped to the wrong conclusion, but it was so reasonable that I
posted a follow-up to that just assuming that he was right.
 
The actual issue is, I believe, purely syntactical: that the `{}` is
only supported syntactically in a (syntactically) function call.
 
For you /can/ write this:
 
if( std::operator==( z, {} ) )
; // empty statement.
 
 
Cheers & hth.,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Jun 12 04:54PM +0300

On 12.06.2016 14:02, Paul wrote:
> if(z == {})
> ; // empty statement.
> }
 
std::operator== is not a member of std::vector, it is a standalone
function which has many overloads. When you pass it z and {} it does not
know which overload because types are not the same and there is no exact
match.
 
There are a couple of workarounds:
 
a) cast/convert the operand into correct type manually:
 
if (z == std::vector<int>({}))
 
 
b) use a function which is not overloaded:
 
bool AreEqual(const std::vector<int>& a, const std::vector<int>& b) {
return a==b;
}
 
...
if (AreEqual(z, {}))
 
Of course, for the problem at hand you could rather use
 
if (z.empty())
 
instead, as suggested by Alf.
 
hth
Paavo
Paavo Helde <myfirstname@osa.pri.ee>: Jun 12 05:15PM +0300

On 12.06.2016 16:34, Alf P. Steinbach wrote:
> posted a follow-up to that just assuming that he was right.
 
> The actual issue is, I believe, purely syntactical: that the `{}` is
> only supported syntactically in a (syntactically) function call.
 
It is supported also in initialization
 
std::vector<int> z = {};
std::vector<int> z2 {};
 
 
> For you /can/ write this:
 
> if( std::operator==( z, {} ) )
> ; // empty statement.
 
Sorry, this does not work:
 
1>main.cpp(26): error C2665: 'std::operator ==' : none of the 5
overloads could convert all the argument types
1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\system_error(410): could be 'bool std::operator ==(const
std::error_condition &,const std::error_code &) throw()'
1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\system_error(402): or 'bool std::operator ==(const
std::error_code &,const std::error_condition &) throw()'
1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\exception(507): or 'bool std::operator ==(const
std::exception_ptr &,std::nullptr_t)'
1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\exception(502): or 'bool std::operator
==(std::nullptr_t,const std::exception_ptr &)'
1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\exception(497): or 'bool std::operator ==(const
std::exception_ptr &,const std::exception_ptr &)'
1> while trying to match the argument list
'(std::vector<int,std::allocator<_Ty>>, initializer-list)'
1> with
1> [
1> _Ty=int
1> ]
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 04:22PM +0200

On 12.06.2016 16:15, Paavo Helde wrote:
 
> It is supported also in initialization
 
> std::vector<int> z = {};
> std::vector<int> z2 {};
 
Yep, thanks!
 
 
> overloads could convert all the argument types
> 1> C:\Program Files (x86)\Microsoft Visual Studio
> 12.0\VC\include\system_error(410):
 
It's a Good Idea to compile code for C++11 and later, with a compiler
that supports the relevant feature(s).
 
You should upgrade from VS 2012 to VS 2015.
 
The latest update is 3, but I've only gotten around to 2.
 
 
{example}
[C:\my\forums\so\156]
> g++ --version | find "++"
g++ (tdm64-1) 5.1.0
 
[C:\my\forums\so\156]
> cl /nologo- 2>&1 | find "++"
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86
 
[C:\my\forums\so\156]
> type foo.cpp
#include <vector>
 
int main()
{
std::vector<int> z;
if( std::operator==( z, {} ) )
; // empty statement.
}
 
[C:\my\forums\so\156]
> g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:7:7: warning: suggest braces around empty body in an 'if'
statement [-Wempty-body]
; // empty statement.
^
 
[C:\my\forums\so\156]
> cl foo.cpp /Feb
foo.cpp
foo.cpp(7): warning C4390: ';': empty controlled statement found; is
this the intent?
 
[C:\my\forums\so\156]
> _
{/example}
 
Which exemplifies that I'm not always so pedantically correct in where I
place the small example code snippets.
 
Hrmf.
 
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 04:27PM +0200

On 12.06.2016 15:54, Paavo Helde wrote:
> function which has many overloads. When you pass it z and {} it does not
> know which overload because types are not the same and there is no exact
> match.
 
No no, passing `z` and `{}` /to the function/ is supported and works
nicely with modern compilers.
 
It's the operator notation that doesn't support `{}`.
 
Else-thread you remarked that it's not only supported syntactically for
function calls, but also for initializers. And I can add to that, also
for `return` statements. Which however can be regarded as initialization
of the returned object.
 
[snip]
 
 
Cheers & hth.,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Jun 12 05:29PM +0300

On 12.06.2016 17:15, Paavo Helde wrote:
 
>> if( std::operator==( z, {} ) )
>> ; // empty statement.
 
> Sorry, this does not work:
 
Correction: it seems this might accidentally work if one avoids
including most standard headers (the errors in my previous post appeared
because of #include <iostream>). However, this is not guaranteed because
standard headers like <vector> can freely include other standard headers.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 04:30PM +0200

On 12.06.2016 16:29, Paavo Helde wrote:
> including most standard headers (the errors in my previous post appeared
> because of #include <iostream>). However, this is not guaranteed because
> standard headers like <vector> can freely include other standard headers.
 
I can report that it works niceley with `<iostream>` included, with g++
5.1 and MSVC 2015.
 
And there's no accident about it. :)
 
 
Cheers & hth.,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Jun 12 06:53PM +0300

On 12.06.2016 17:30, Alf P. Steinbach wrote:
 
> I can report that it works niceley with `<iostream>` included, with g++
> 5.1 and MSVC 2015.
 
> And there's no accident about it. :)
 
I see. That's nice to hear. It seems I need to upgrade indeed.
 
I wonder if there have been any changes in this area in C++ standards or
is it just another MSVC bug?
 
Cheers
Paavo
Vir Campestris <vir.campestris@invalid.invalid>: Jun 12 06:15PM +0100

On 12/06/2016 15:22, Alf P. Steinbach wrote:
> You should upgrade from VS 2012 to VS 2015.
 
> The latest update is 3, but I've only gotten around to 2.
 
I take it you heard about the telemetry thing?
 
Andy
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: Jun 12 11:46AM +0200


>>> https://yro.slashdot.org/story/16/06/10/1350245/visual-studio-2015-c-compiler-secretly-inserts-telemetry-code-into-binaries
 
[...]
> But this brings up a very important point (one which I saw back in the
> 90's but hasn't been followed up in much). We all trust our compilers
> and libraries not to add extra code. But is this trust misplaced?
 
One of the comments on the slashdot page refers to "the Ken Thompson
attack", described at http://c2.com/cgi/wiki?TheKenThompsonHack
 
Ken Thompson notes ("Reflections on Trusting Trust" are available from
http://dl.acm.org/citation.cfm?id=358210 (or
http://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf)
 
-- Alain.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 12 03:51AM +0100

Hi all,
 
Line edits, spin boxes, sliders and modal dialogs implemented in my
upcoming Cross-platform C++ GUI/game library "neogfx":
 
http://neogfx.org
 
/Flibble
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: