Tuesday, December 29, 2015

Digest for comp.lang.c++@googlegroups.com - 24 updates in 7 topics

Paul <pepstein5@gmail.com>: Dec 29 06:16AM -0800

I am writing code to swap elements of vectors of general type and reverse vectors. The following code (see below asterisks) has been tested and seems to work (so far).
 
But clearly, this is reinventing the wheel. My reverse function swaps so surely it should implement the swap function. However, I can't write it that way without getting a compile error. If I replace the body of the for loop
by swap<T>(vec[i], vec[j]); then I get a compile error (which follows an attempted function call) that the swap function can't be matched. I'd be grateful if someone could explain why swap<T>(vec[i], vec[j]); is ambiguous and what I should do about it.
 
Many thanks for your help.
 
Paul
 
 
***************************************************
template<typename T>
void swap(T& x, T&y)
{
T tmp = x;
x = y;
y = tmp;
}
 
template<typename T>
void reverse(vector<T>& vec)
{
if(vec.empty())
return;
 
for(int i = 0, j = vec.size() - 1; i < j; ++i, --j)
{
T tmp = vec[i];
vec[i] = vec[j];
vec[j] = tmp;
}
}
Paavo Helde <myfirstname@osa.pri.ee>: Dec 29 08:59AM -0600

Paul <pepstein5@gmail.com> wrote in
> function can't be matched. I'd be grateful if someone could explain
> why swap<T>(vec[i], vec[j]); is ambiguous and what I should do about
> it.
 
The code might conflict with std::swap(). If you want better help, post a
complete failing code example and error messages.
 
hth
Paavo
Paul <pepstein5@gmail.com>: Dec 29 07:17AM -0800

On Tuesday, December 29, 2015 at 3:00:11 PM UTC, Paavo Helde wrote:
> complete failing code example and error messages.
 
> hth
> Paavo
 
Ok, complete code and error messages are below. I have renamed swap to remove that concern. Many thanks.
 
Paul
 
#include <iostream>
#include <stdexcept>
#include <vector>
using std::vector;
 
template<typename T>
void swap1(T& x, T&y)
{
T tmp = x;
x = y;
y = tmp;
}
 
template<typename T>
void reverse(vector<T>& vec)
{
if(vec.empty())
return;
 
for(int i = 0, j = vec.size() - 1; i < j; ++i, --j)
swap1<T>(vec[i], vec[j]);
}
 
int main()
{
vector<bool> vec = {true, false, false};
reverse<bool>(vec);
for(int i = 0; i < vec.size(); ++i)
std::cout << std::endl << vec[i];
 
}
 
Errors are:
 
||=== Build: Debug in reverse (compiler: GNU GCC Compiler) ===|
C:\Users\silviadaniel\Desktop\reverse\main.cpp||In function 'int main()':|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|28|warning: comparison between signed and unsigned integer expressions [-Wsign-compare]|
C:\Users\silviadaniel\Desktop\reverse\main.cpp||In instantiation of 'void reverse(std::vector<T>&) [with T = bool]':|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|27|required from here|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|21|error: no matching function for call to 'swap1(std::vector<bool>::reference, std::vector<bool>::reference)'|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|21|note: candidate is:|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|7|note: template<class T> void swap1(T&, T&)|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|7|note: template argument deduction/substitution failed:|
C:\Users\silviadaniel\Desktop\reverse\main.cpp|21|note: cannot convert '(& vec)->std::vector<bool, _Alloc>::operator[]<std::allocator<bool> >(((std::vector<bool>::size_type)i))' (type 'std::vector<bool>::reference {aka std::_Bit_reference}') to type 'bool&'|
||=== Build failed: 1 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 29 04:47PM +0100

On 12/29/2015 4:17 PM, Paul wrote:
 
> int main()
> {
> vector<bool> vec = {true, false, false};
 
vector<bool> is specialized to allow the bools to be represented with
one bit each.
 
Consequently you do not get real references to `bool` items, but instead
proxy objects that act somewhat like references:
 
(constructor)
constructs the reference. Accessible only to std::vector<bool> itself
(public member function)
(destructor)
destroys the reference
(public member function)
operator=
assigns a bool to the referenced bit
(public member function)
operator bool
returns the referenced bit
(public member function)
flip
flips the referenced bit
(public member function)
 
From <url:
http://en.cppreference.com/w/cpp/container/vector_bool/reference>
(except that term "lvalue" there is misplaced, maybe very informal, or
else just wrong).
 
One alternative, when you want that, is a `dequeue<bool>`. In the other
direction, you could generalize the swap function with an overload that
handles this case.
 
 
> for(int i = 0; i < vec.size(); ++i)
> std::cout << std::endl << vec[i];
 
> }
 
Cheers & hth.,
 
- Alf
Cholo Lennon <chololennon@hotmail.com>: Dec 29 12:53PM -0300

On 12/29/2015 12:17 PM, Paul wrote:
> C:\Users\silviadaniel\Desktop\reverse\main.cpp|21|error: no matching
> function for call to 'swap1(std::vector<bool>::reference,
> std::vector<bool>::reference)'|
 
std::vector<bool> is not the best option to test your algorithm. Check this:
 
http://stackoverflow.com/questions/17794569/why-is-vectorbool-not-a-stl-container
 
 
 
Regards
 
 
--
Cholo Lennon
Bs.As.
ARG
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 29 04:58PM +0100

On 12/29/2015 4:47 PM, Alf P. Steinbach wrote:
 
> One alternative, when you want that, is a `dequeue<bool>`. In the other
> direction, you could generalize the swap function with an overload that
> handles this case.
 
OK, I checked how `std::reverse` does it, and it uses `std::iter_swap`
instead of using `std::swap` directly.
 
 
Cheers & hth.,
 
- Alf
Daniel <danielaparker@gmail.com>: Dec 29 08:10AM -0800

On Tuesday, December 29, 2015 at 10:47:42 AM UTC-5, Alf P. Steinbach wrote:
> one bit each.
 
> Consequently you do not get real references to `bool` items, but instead
> proxy objects that act somewhat like references:
 
This seems to work (with VS 2015):
 
template<typename T>
void reverse(vector<T>& vec)
{
if (vec.empty())
return;
 
using std::swap;
 
for (int i = 0, j = vec.size() - 1; i < j; ++i, --j)
swap(vec[i], vec[j]);
}
 
int main()
{
vector<bool> vec = { true, false, false };
reverse<bool>(vec);
for (int i = 0; i < vec.size(); ++i)
std::cout << std::endl << vec[i];
}
 
Output:
 
0
0
1
Paul <pepstein5@gmail.com>: Dec 29 08:33AM -0800

On Tuesday, December 29, 2015 at 4:10:54 PM UTC, Daniel wrote:
 
> 0
> 0
> 1
 
Yes, using std::swap works (on any compiler). I was trying to write the code myself, rather than using library functions.
 
Paul
pepstein5@gmail.com: Dec 29 08:39AM -0800

On Tuesday, December 29, 2015 at 4:34:03 PM UTC, Paul wrote:
> > 0
> > 1
 
> Yes, using std::swap works (on any compiler). I was trying to write the code myself, rather than using library functions.
 
Sorry, I take that back. std::swap doesn't work on my compiler in the above example -- gcc. Interesting that VS 2015 accepts my example.
 
Paul
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 29 05:47PM +0100

On 12/29/2015 5:33 PM, Paul wrote:
 
> Yes, using std::swap works (on any compiler). I was trying to write
> the code myself, rather than using library functions.
 
I failed to find that specialization over at cppreference.com, but
finally found it in C++11 §23.3.7/5:
 
static void swap(reference x, reference y) noexcept;
 
So, it's not just a compiler-specific extension.
 
 
Cheers & hth.,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Dec 29 10:53AM -0600

Paul <pepstein5@gmail.com> wrote in
>:_Bit_reference}') to type 'bool&'|
>||=== Build failed: 1 error(s), 3 warning(s) (0 minute(s), 0 second(s
> )) ===|
 
 
std::vector<bool> is a more or less failed experiment by the C++ standard
committee; for supporting it you need to provide special specialization
or overload of your swap1() (assuming you don't want to just use
std::swap() by whatever reasons):
 
#include <iostream>
#include <stdexcept>
#include <vector>
using std::vector;
 
template<typename T>
void swap1(T& x, T&y) {
T tmp = x;
x = y;
y = tmp;
}
 
void swap1(vector<bool>::reference x, vector<bool>::reference y) {
bool tmp = x;
x = y;
y = tmp;
}
 
template<typename T>
void reverse(vector<T>& vec) {
if (vec.empty())
return;
 
for (int i = 0, j = vec.size() - 1; i < j; ++i, --j)
swap1(vec[i], vec[j]);
}
 
int main() {
vector<bool> vec = {true, false, false};
reverse<bool>(vec);
for (int i = 0; i < vec.size(); ++i)
std::cout << std::endl << vec[i];
 
}
Marcel Mueller <news.5.maazl@spamgourmet.org>: Dec 29 08:00PM +0100

On 29.12.15 15.16, Paul wrote:
> x = y;
> y = tmp;
> }
 
Do not redefine the standard function swap. This is probably your problem.
 
 
Marcel
Mr Flibble <flibble@i42.co.uk>: Dec 29 07:13PM

On 29/12/2015 19:00, Marcel Mueller wrote:
>> y = tmp;
>> }
 
> Do not redefine the standard function swap. This is probably your problem.
 
Unless this function template is in the std namespace he is not
redefining the standard function swap. Overloading swap is sometimes
useful sausages.
 
/Flibble
Marcel Mueller <news.5.maazl@spamgourmet.org>: Dec 29 10:21PM +0100

On 29.12.15 20.13, Mr Flibble wrote:
>> problem.
 
> Unless this function template is in the std namespace he is not
> redefining the standard function swap.
 
bad code style anyway.
 
> Overloading swap is sometimes
> useful sausages.
 
Yes, but only as partial specialization for custom types.
 
 
Marcel
Mr Flibble <flibble@i42.co.uk>: Dec 29 09:47PM

On 29/12/2015 21:21, Marcel Mueller wrote:
 
>> Unless this function template is in the std namespace he is not
>> redefining the standard function swap.
 
> bad code style anyway.
 
Only because he is not specializing it for custom types sausages.
 
/Flibble
Jorgen Grahn <grahn+nntp@snipabacken.se>: Dec 29 02:15PM

On Sat, 2015-12-26, JiiPee wrote:
 
>>> I wonder why the compiler does not give an error here? I think it should
>>> be like that: unsigned must be converted with static_cast to int, and
>>> otherwise its a compilation error. Thats how it should be imo.
 
But it's not, and it's not possible to change without breaking lots of
code and C compatibility.
 
 
> yes ok, that might the solution then. even for the OP. Although
> personally I do not see this so much a problem currently as I rarely use
> unsigned... I just use int almost everywhere.
 
That's hard to do in practice, since so many things in the language
(size_t, container<T>::size_type and so on) are unsigned. If you
choose to use int, you'll have a suspicious conversion as soon as you
use those things.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 29 04:33PM +0100

On 12/29/2015 3:15 PM, Jorgen Grahn wrote:
> (size_t, container<T>::size_type and so on) are unsigned. If you
> choose to use int, you'll have a suspicious conversion as soon as you
> use those things.
 
It's very easy to use signed types (preferably just "int") for integral
numbers throughout the code, simply by defining a [1]few general size
functions, like `static_size`, `n_items` and `length`.
 
It didn't used to be that way, e.g. because g++ erroneously & stubbornly
used to refuse to infer an array type for a template where the size was
signed.
 
Happily, as with the earlier g++ steadfast opposition to the UTF-8 BOM
(directly opposite of the requirements of the Visual C++ compiler, and
with the proponents never once acknowledging that that was the reason,
but instead going on about all kinds of silly ideals), those days of
by-compiler-as-proxy wars seem to be over. Let's hope it's for real.
 
 
Cheers & hth.,
 
- Alf
 
Notes:
[1] See <url:
https://github.com/alf-p-steinbach/cppx/blob/plutonium/core_language_support/sizes_and_lengths.hpp>
for an example implementation. I'm currently adding an `is_empty`
function to that mix. But I haven't tested it: it's supposed to
automatically ues a boolean `is_empty()`, `isEmpty`, `IsEmpty` or
`empty()` member function if one exists, where the last one is the
standard lib's convention.
JiiPee <no@notvalid.com>: Dec 29 03:37PM

On 26/12/2015 12:46, Paul wrote:
>> personally I do not see this so much a problem currently as I rarely use
>> unsigned... I just use int almost everywhere.
> Ok, except that ints might not work very well for Ferrero Rocher chocolates. Since they taste so good (particularly at holiday times where you can eat guilt-free), you might want to use unsigned to buy 2^32-1 of them rather than an int-based approach which lets you eat only 2^31-1. Ints for the dieters, but unsigneds for those who want to maximise consumption.
 
so you see.... its only one difference in exponent 32 <-> 31. I dont
know why people make that difference so big issue... they are both big
numbers anyway...
Jorgen Grahn <grahn+nntp@snipabacken.se>: Dec 29 03:22PM

On Wed, 2015-12-23, Stefan Ram wrote:
> is used from the command line with shell redirection of stdin
> via »<« or I could accept the path of the file via »argc« and
> then construct an »ifstream« object. Which possibility is better?
 
That's not a C++ question; that's a question of user interface,
regardless of language (as a user I don't care what language the
program is written in).
 
For Unix programs, I prefer to do what cat(1), Perl's "while(<>)"
construct and many others do. That is, if it makes sense for your
program to take multiple files and see them more or less as one long
text stream.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
bleachbot <bleachbot@httrack.com>: Dec 29 03:09PM +0100

Ramine <ramine@1.1>: Dec 29 09:09AM -0800

Hello,
 
This was my last post on this forum.
 
 
Thank you,
Amine Mouklay Ramdane.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Dec 29 12:24PM

>> do there was to create a counter<T> class and use it instead of
>> unsigned, unsigned long etc.
 
> In highly iterative code,
 
I don't know what "iterative" means in this context, I'm afraid.
I was talking mostly about class members in the paragraph above,
because that's what David Brown did.
 
> initialization site before visiting the implementation site. Very
> often though, I truly have an int or a bool, not a counter<> or some
> other widget<>.
 
Ok. Note the /sometimes/ above; I'm not claiming it applies to you.
 
Although I note that to a lot of people, my counters would "truly" be
integers, too. A common mistake among C++ programmers is that they use
the builtin types too much; their own classes are big, long-lived
things.
 
> make "class Int" and "class Bool" to use in this type of script-y
> code. Perhaps I'm being too curmudgeonly here, but the very thought
> makes me nauseous.
 
Yes; such code would look very unusual.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Paavo Helde <myfirstname@osa.pri.ee>: Dec 29 03:13AM -0600

serge.robyns@gmail.com wrote in
 
>> you should use Ada.
 
> This Amine guy has been spamming the Ada newsgroup too and all his
> post have been flagged as spam.
 
Darn, it looks like my secret plan to coax him away from c.l.c++ has failed
;-)
"Öö Tiib" <ootiib@hot.ee>: Dec 29 02:21AM -0800

On Tuesday, 29 December 2015 11:14:14 UTC+2, Paavo Helde wrote:
> > post have been flagged as spam.
 
> Darn, it looks like my secret plan to coax him away from c.l.c++ has failed
> ;-)
 
Seems that comp.lang.c has done the trick somehow. He has not cross-posted his
spam to there since August.
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: