- How to split a char array? - 5 Updates
- New address of the C Containers library - 3 Updates
- template method of functor "can't deduce template parameter" - 1 Update
- assignment and implicit conversion - 6 Updates
- Function arguments and braced initializer lists - 1 Update
- list of operating systems that can run C++? - 4 Updates
- (int(*)(int)) ? - 2 Updates
- Validation of my USL program - 1 Update
- std::initializer_list assignment operator - 2 Updates
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Mar 30 09:04PM +0200 Am 30.03.2016 um 17:25 schrieb Geoff: >>>>>>>> Am 27.03.2016 um 15:03 schrieb Alf P. Steinbach: >>>>>>>>> On 27.03.2016 11:17, Heinz-Mario Frühbeis wrote: >> [...] [...] > Since you were copying a const char *nString, I assumed you knew where > it was coming from and would obtain the lock on that string before > copying it to the local mutable string for manipulation. I know, what I experience... std::string.c_str works, std::string not. Regards Heinz-Mario Frühbeis |
Dombo <dombo@disposable.invalid>: Mar 30 09:59PM +0200 Op 30-Mar-16 om 16:38 schreef Mr Flibble: >> That makes a big difference in efficiency. > x is a constant though so it makes no difference as far as algorithmic > "efficiency" (complexity) is concerned. But it does make a difference as far as effective speed and memory fragmentation is concerned. |
Geoff <geoff@invalid.invalid>: Mar 30 08:25AM -0700 On Wed, 30 Mar 2016 09:58:54 +0200, Heinz-Mario Frühbeis >callback function e.g. from a loop which is runnnung in a pthread, you >can only use c_str, also *not length(). Else, undef behaviour, or even >crash... If you are using memmove or strlen without obtaining appropriate locks then you are not thread safe. It makes no difference if you are using the c_str member or not, you are still accessing the same object and if you don't own the lock on it you are not thread safe. Your experiment is flawed and your statement above is incorrect. Thread safety is YOUR problem, not the functions and not the objects (necessarily). You asked about string manipulation and splitting and presented non-threaded C code. I showed you an example of a non-threaded C++ way to do it. Thread safety is a separate issue. Since you were copying a const char *nString, I assumed you knew where it was coming from and would obtain the lock on that string before copying it to the local mutable string for manipulation. |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Mar 30 01:09PM +0200 Am 30.03.2016 um 11:20 schrieb Alf P. Steinbach: > former, then its unsafe with the latter, and vice versa, except that its > easier to introduce bugs with C style strings. > Cheers & hth., Here, I have a XLib-Event-Loop running in a pthread and *every access on std::string in a callback-function from this loop results in an error, except I'm using c_str! E.g.: std::string string_var; if(string_var.length() > 0){ // ERROR } if(strlen(string_var.c_str) > 0){ // NO ERROR } if(string_var == "HALLO"() > 0){ // ERROR } if(string_var.c_str == "HALLO"){ // NO ERROR } To me, it seems to be the same behaviour like XLib has... Regards Heinz-Mario Frühbeis |
leigh.v.johnston@googlemail.com: Apr 04 09:10AM -0700 ptr_vector requires two different allocators and allocation strategies whilst std::list requires just one. std::list is often better than both vector and ptr_vector if there are frequent insertions/erases in the middle. Support for polymorphic types is a different kettle of fish and use-cases. |
jacobnavia <jacob@jacob.remcomp.fr>: Mar 30 03:03PM +0200 https://github.com/jacob-navia/ccl.git There you will find all the source code and the source code of the dopcumentation in TeX form (the only word processor of the 80es that is still running today and will run in 2030) The C Containers library is a replica of the STL written in plain C. jacob |
scott@slp53.sl.home (Scott Lurndal): Mar 30 04:12PM >> run through 2030, and is still the foundation of manual pages >> on unix/linux systems. >Or perhaps nroff. It's the same source language - troff generates typesetter output (now postscript) and nroff generates terminal output. >> If you are documenting source code, then you should at minimum >> provide doxygen comments in the source. >Seriously? doxygen is a train wreck. YMMV. |
Keith Thompson <kst-u@mib.org>: Apr 04 08:29AM -0700 jacobnavia <jacob@jacob.remcomp.fr> writes: [...] > printf("sizeof(Dlist)=%lu\n",sizeof(Dlist)); [...] That should be %zu, not %lu. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
kurt.krueckeberg@gmail.com: Apr 04 07:38AM -0700 g++ with std=c++14 is giving me a "couldn't deduce template parameter 'Key'" error, on a template method of a functor class (that isn't itself a template). I can't figure out why. The code looks like it should work. I am implementing a 2 3 tree, and it has a level order traversal method that takes a functor. operator. The tree23 code is basically this: template<class Key, class Value> class tree23 { public: class Node23 { friend class tree23<Key, Value>; public: // snip... friend std::ostream& operator<<(std::ostream& ostr, const Node23& node23) { // snip... outputs the keys and values of node23 to ostr. } private: Node23 *parent; std::array<Key, 2> keys; std::array<Value, 2> values; std::array<std::unique_ptr<Node23>, 3> children; int totalItems; // either TwoNodeItems or ThreeNodeItems // snip... }; template<typename Functor> void levelOrderTraverse(Functor f) const noexcept; // snip... }; The level order traversal invokes the functor's function call operator, passing it two parameters. template<class Key, class Value> template<typename Functor> \ void tree23<Key, Value>::levelOrderTraverse(Functor f) const noexcept { std::queue< std::pair<const Node23*, int> > queue; Node23 *proot = root.get(); if (proot == nullptr) return; auto initial_level = 1; // initial, top level is 1, the root. queue.push(std::make_pair(proot, initial_level)); while (!queue.empty()) { std::pair<const Node23 *, int> pair_ = queue.front(); const Node23 *current = pair_.first; int current_tree_level = pair_.second; // invokes functor's operator()(const Node23&, int)? f(*current, current_tree_level); if (!current->isLeaf()) { for(auto i = 0; i < current->getChildCount(); ++i) { queue.push(std::make_pair(current->children[i].get(), current_tree_level + 1)); } } queue.pop(); } } The functor is quite simple: class levelOrderPrinter { private: // snip... public: levelOrderPrinter(std::ostream& ostr_lhs, int depth); levelOrderPrinter(levelOrderPrinter&); levelOrderPrinter(const levelOrderPrinter&); template<class Key, class Value> void operator()(const typename tree23<Key, Value>::Node23& node, int current_level) noexcept; }; template<class Key, class Value> void levelOrderPrinter::operator()(const typename tree23<Key, Value>::Node23& node, int current_level) noexcept { // Did level change? if (level != current_level) { level = current_level; ostr << "\n\n" << "level = " << level; // Provide some basic spacing to tree appearance. std::size_t num = tree_depth - level + 1; std::string str( num, ' '); ostr << str; } ostr << node; } |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 31 07:23AM I am trying to learn a little bit about assignment in C++. I have a vague memory that one can write some »constructor arguments« even after »return« or as a function argument, and then C++ will consider these values for implicit creation of an object of the required type. But I used to believe that this was not allowed in an assignment. Now, I tried this: #include <initializer_list> #include <iostream> #include <ostream> #include <string> using namespace ::std::literals; struct sigma { sigma( ::std::string const s ): x{ 1 }{} sigma( ::std::initializer_list<::std::string> const s ): x{ 2 }{} int x; }; int main() { sigma s{ "abc"s }; ::std::cout << s.x << '\n'; /* prints 2 */ s = "abc"s; ::std::cout << s.x << '\n'; /* prints 1 */ s ={ "abc"s }; ::std::cout << s.x << '\n'; /* prints 2 */ ::std::cout << "done.\n"s; } So it seems that one now can write a »constructor argument« for the RHS of the assignment and then C++ will do an implicit creation of a temporary with those expression as »constructor arguments«. Even with initializer lists! Or maybe this was always possible and I just did not know? Did I use the right words to describe what is happening? And since when is this allowed? (This is actually the central question of this post! I have a vague memory that initializer_lists where not always allowed in the RHS of an assignment.) So, one can use »constructor arguments« for a creation of an object in these places that I am aware of: - of course in a variable declaration - in a function-style cast - and I believe also in a static_cast - in a condition (e.g., "if( int x = ... )", 6.4p1) - in the RHS of an assignment (as being described above) - after a »return« - as an argument value - as an argument of emplace_back (but this might be just a special case of the preceding case) - Did I miss any cases? Are there any differences between these cases (in the sense that some types of constructions are only possible with some of these cases but not with others)? The common property of all these cases seems to be that the context gives an information about an »expected type«. |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 01 12:53AM #include <iostream> #include <string> void print( ::std::string s ){ ::std::cout << s << '\n'; } int main() { print( "alpha" ); print( { "alpha" } ); print( { { "alpha" }} ); /* print( { { { "alpha" }}} ); */ /* No! */ } Why are two nestings allowed, but not three? |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 31 09:54PM >And since when is this allowed? (This is actually the central >question of this post! I have a vague memory that initializer_lists >where not always allowed in the RHS of an assignment.) Seems to be C++14. |
bleachbot <bleachbot@httrack.com>: Apr 02 01:24AM +0200 |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 31 06:44PM >I am trying to learn a little bit about assignment in C++. Now, a followup. The program was compiled and executed with GCC 5.1.1 and »-std=c++17«. In detail, the options were: -mwindows -msse2 -march=native -Ofast -O3 -std=c++17 -pedantic -pedantic-errors -Werror=narrowing -Wall -W -Wconversion -Wextra -Weffc++ -Wno-parentheses -Wno-unused-parameter -Wno-unused-variable -pthread #include <initializer_list> #include <iostream> #include <ostream> #include <string> #include <vector> using namespace ::std::literals; struct sigma { sigma( ::std::string const s ): x{ 1 }{} sigma( ::std::initializer_list<::std::string> const s ): x{ 2 }{} operator bool(){ return false; } int x; }; sigma f( sigma x ){ return { "a"s, "b"s }; } void try_out_sigma() { sigma s{ "abc"s }; ::std::cout << s.x << '\n'; s = "abc"s; ::std::cout << s.x << '\n'; s ={ "abc"s }; ::std::cout << s.x << '\n'; s ={ "a"s, "b"s }; ::std::cout << s.x << '\n'; f( { "a"s, "b"s } ); sigma t = sigma{ "a"s, "b"s }; ::std::cout << t.x << '\n'; /* sigma u = static_cast< sigma >( { "a"s, "b"s }); *//* No! */ sigma u = static_cast< sigma >( "a"s ); /* No! */ ::std::vector<sigma> v; v.emplace_back( "a"s ); /* v.emplace_back( { "a"s, "b"s } ); *//* No! Why? */ if( s ){} if( sigma{ "a"s, "b"s } ){} if( sigma t = "abc"s ){} if( sigma t{ "a"s, "b"s } ){} ::std::cout << "done.\n"s; } struct eta /* = explicit sigma */ { explicit eta( ::std::string const s ): x{ 1 }{} explicit eta( ::std::initializer_list<::std::string> const s ): x{ 2 }{} explicit operator bool(){ return false; } int x; }; void f( eta x ){ return; /* return { "a"s, "b"s }; */ /* No, explict! */ } void try_out_eta() { eta s{ "abc"s }; ::std::cout << s.x << '\n'; /* still ok */ /* s = "abc"s; ::std::cout << s.x << '\n'; */ /* No, explict! */ /* s ={ "abc"s }; ::std::cout << s.x << '\n'; */ /* No, explict! */ /* s ={ "a"s, "b"s }; ::std::cout << s.x << '\n'; */ /* No, explict! */ /* f( { "a"s, "b"s } ); */ /* No, explict! */ eta t = eta{ "a"s, "b"s }; ::std::cout << t.x << '\n'; /* still ok */ eta u = static_cast< eta >( "a"s ); /* still ok */ ::std::cout << u.x << '\n'; ::std::vector<eta> v; v.emplace_back( "a"s ); /* still ok */ if( s ){} /* still ok! Why? */ if( eta{ "a"s, "b"s } ){} /* if( eta t = "abc"s ){} *//* No, explict! */ if( eta t{ "a"s, "b"s } ){} /* still ok */ ::std::cout << "done.\n"s; } int main() { try_out_sigma(); try_out_eta(); } I have marked what I did not understand immediately with »Why?«. I observed that with GCC 5.1.1 and »-std=c++17«, I can write »if( s )« even though operator bool is explicit in »eta«. I remember that folks told me here that I cannot write »if( ::std::cin )« anymore, because something was »explicit«. Then why can I write »if( s )« above, when s is of type »eta« with an explicit operator bool()? I also tried »-Wno-unused-but-set-variable« to suppress »[Warning] variable 'u' set but not used [-Wunused-but-set-variable]«, but the warning still appears. |
bleachbot <bleachbot@httrack.com>: Apr 02 01:23AM +0200 |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 31 08:31PM -0500 > Therefore, argument passing is more fundamental than > assignment expressions, so one cannot use assignment > expressions to explain argument passing in a strict text. Your absurd habit of writing ::std instead of std continues to irritate mate; well done. /Flibble |
Johann Klammer <klammerj@NOSPAM.a1.net>: Mar 30 09:22AM +0200 On 03/29/2016 10:27 PM, Christopher Pisz wrote: > Does there exist a list of operating systems/hardware that I can target in C++? > My office mate is arguing with me that C# is now more portable than C++, because...mono. He is making me angry. Isn't mono another one of those platforms that emulate a non-existent architecture and the emulator runs only on a very small subset of actually existing architectures? (like java?) |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Mar 30 08:47PM +0200 On 30.03.16 19.07, Bo Persson wrote: [VM with git vs. C++] > So, to have optimal performance you either download an executable > specifically optimized for your system, or a JVM with specific > optimizations for your system. Except that the latter has to be done only once for each platform while the optimized executable has to be build for the cross product of platforms and applications. In real live no one does the latter. Even common Linux distributions target only roughly the hardware. So many new CPU features are unused by most of the applications. Some exceptions prove the rule, of course. E.g. the FFTW library comes with optimized assembler code for many architectures. Marcel |
David Brown <david.brown@hesbynett.no>: Mar 31 09:09AM +0200 On 31/03/16 06:38, Ian Collins wrote: >> portability (as they claim) but it'll only run on windowze, >> something has to be wrong, no? > Ah, but it is portable across all supported versions of windows :) All supported versions of windows that have the right service packs, updates, hotfixes, etc., of the right version of the dotnet libraries... And of course there is the microcontroller ".net Micro Framework", if anyone actually uses it. |
Ian Collins <ian-news@hotmail.com>: Mar 31 05:38PM +1300 On 03/31/16 17:34, Johann Klammer wrote: > I mean it's a nice marketing spin and all, but if the goal is > portability (as they claim) but it'll only run on windowze, > something has to be wrong, no? Ah, but it is portable across all supported versions of windows :) -- Ian Collins |
scott@slp53.sl.home (Scott Lurndal): Mar 31 07:40PM >What are each of the parts in the brackets? >I am see C-style cast (int)myvariable, but never >(type(otherstuff)(morestuff))function It's a function pointer to a function returning int with a single int parameter. |
jt@toerring.de (Jens Thoms Toerring): Mar 31 08:52PM > Can someone break this cast down for me? > Example: (int (*)(int))std::toupper If you have a defintion like this int (*foo)(double); 'foo' is a pointer variable to a function that takes an double as its (only) argument and returns an int. And, in that spirit, (int (*)(int)) std::toupper casts the address of the std::toupper function to a pointer to a function that takes an int argument and returns an int. You can also use this with typedefs, e.g. typedef void (*sighandler_t)(int); makes 'sighandler_t a type that is pointer to a function that takes an int argument and returns void. This is used in the declaration of the UNIX signal() function which sets up a handler function (taking an int and returning void) for the signal numbered 'signo' (and returns the previous handler): sighandler_t signal(int signum, sighandler_t handler); which would be a handful to parse without the typedef: void (signal(int, void (*)(int)))(int, void (*)(int)); (I hope I got that right;-) > What are each of the parts in the brackets? > I am see C-style cast (int)myvariable, but never > (type(otherstuff)(morestuff))function That's probably not what your'e going to see (at least I don't know what it would be supposed to mean;-), it's more more like (rettype (*)(argtype1, argtype2)) function which casts the address of 'function' to a pointer to a function which returns 'rettype' and accepts two arguments, the first one of type 'argtype1' and the second of type 'argtype2'. Regards, Jens -- \ Jens Thoms Toerring ___ jt@toerring.de \__________________________ http://toerring.de |
Ramine <ramine@1.1>: Apr 01 07:24PM -0700 Hello.......... How can you be sure that my USL program works correctly ? Please take a look at this link: https://cran.r-project.org/web/packages/usl/vignettes/usl.pdf Notice the raytracer performance data, when they have analysed it, it gives a peak scalability at: 449 So try to run my program inside the zip against the the same raytracer performance data that you will find inside the data.csv file inside the zip, and this will give the same peak scalability at: 449. So as you have noticed, my program is working for this performance data of the raytracer, so i think that you can be confident with my program. I have included an executable called usl.exe inside the zip, please read the readme file to know how to use it, it is a very powerful tool. Thank you, Amine Moulay Ramdane. |
hbdevelop1@gmail.com: Apr 03 10:13PM -0700 Hi all, In the code below, an assignment operator is used on the second line in main function. I am curious to see how the initializer_list assignment operator looks like but I can't find its code in the STL library. The class definition in /usr/include/c++/5/initializer_list does not provide any assignment operator. Could anyone please tell me in which file it is defined ? Thank you in advance // initializer_list example #include <iostream> // std::cout #include <initializer_list> // std::initializer_list int main () { std::initializer_list<int> mylist; mylist = { 10, 20, 30 }; ///<---------- ??????? std::cout << "mylist contains:"; for (int x: mylist) std::cout << ' ' << x; std::cout << '\n'; return 0; } |
"Öö Tiib" <ootiib@hot.ee>: Apr 03 11:23PM -0700 > I am curious to see how the initializer_list assignment operator looks like but I can't find its code in the STL library. > The class definition in /usr/include/c++/5/initializer_list does not provide any assignment operator. > Could anyone please tell me in which file it is defined ? As legacy from C the C++ compiler makes assignment operators implicitly for structs/classes when it is not explicitly done by user. Besides that 'std::initializer_list' is a "magical" class and so not all of its behavior is possible to implement as library code. |
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