- Simple generalised reverse problem. - 15 Updates
- Here is why C and C++ are bad... - 3 Updates
- Best practices (like for file I/O) - 1 Update
- cmsg cancel <n5u422$qj7$1@dont-email.me> - 1 Update
- My last post on this forum - 1 Update
- uninitialized build-in types - 1 Update
- Now i want to talk about Strong typed safety systems - 2 Updates
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:
Post a Comment