comp.lang.c++@googlegroups.com | Google Groups | ![]() |
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
- String's data type - 8 Updates
- MSVC++ anonymous union in struct -- compile-time initialization of non-first member - 3 Updates
- Visual C++ Version 6 (Visual Studio 98) - 1 Update
- I have "inherited" some C++ code.... - 3 Updates
- copying from an input stream into a string - 1 Update
- initializer list - 1 Update
- Help with operator overloading definition and (possibly) link problems - 5 Updates
- Are raw pointers acceptable when used only internally within a class implementation? - 2 Updates
- Extending type traits from <type_traits> - 1 Update
JiiPee <no@notvalid.com>: Sep 18 11:59AM +0100 In all examples of creating a string class they always do it like this: class String { public: // functions ... private: char* str; int len; }; But listening experts they always say that we should not use the old C array but rather vector. So why String is not done like: class String { public: // functions ... private: vector<char> str; }; ? Is it somehow slower? I would actully prefer the vector as its c++. Its like this in all C++ tutorials. |
Wouter van Ooijen <wouter@voti.nl>: Sep 18 01:13PM +0200 JiiPee schreef op 18-Sep-14 12:59 PM: > ? > Is it somehow slower? I would actully prefer the vector as its c++. > Its like this in all C++ tutorials. There is an good std::string, so creating a custom (heap based) string is for educational purposes only. Your first version uses only C-level 'first principles'. It shows how memory can be allocated on the heap, maybe resized, that you must obey the rule of (at least) 3 to make things work properly, etc. It shows the *guts* of how a string class can work. The second version relies on std::vector, which is itself implemented somewhat like the first version, to do all the dirty work. It might still be useful to explain the interface of the string, but it hides all the implementation details. So which one to choose depends on what you want to explain. Wouter van Ooijen |
JiiPee <no@notvalid.com>: Sep 18 12:13PM +0100 Ah, sending messages before thinking it through. Obviously needs a character array as C because thats the representation of strings, we cannot for example "cout<<" a vector. My mistake...I wish I could delete these messages :) On 18/09/2014 11:59, JiiPee wrote: |
JiiPee <no@notvalid.com>: Sep 18 12:16PM +0100 On 18/09/2014 12:13, Wouter van Ooijen wrote: > all the implementation details. > So which one to choose depends on what you want to explain. > Wouter van Ooijen Ok, but I just found out myself that vector is not usefull because we cannot do: cout<<str; if str is a vector. So string class must return a char* type pointer, isnt it? But hmmmm.... can we actually get that char* from vector? I remember reading that vector can be changed to char*, I remember correctly? |
JiiPee <no@notvalid.com>: Sep 18 12:19PM +0100 hmmm, am still actually thinking... as I mentioned, I remember reading that vector<char> can return a char* pointing to the first character of the vector... have to study a bit more about it. On 18/09/2014 12:13, JiiPee wrote: |
JiiPee <no@notvalid.com>: Sep 18 12:22PM +0100 Okey, but I think that is more like a question that do we need C type arrays anymore at all? I mean if I am teaching C++ I would like to teach the correct way to do things. Using a C arrays would teach wrong ways to program C++ , isn't it? On 18/09/2014 12:13, Wouter van Ooijen wrote: |
JiiPee <no@notvalid.com>: Sep 18 12:28PM +0100 |This will return char* : (|char| *)(&str[0]) But obviously it can only be return for reading, not modifying the vector. This would work with the String class in all situations? | On 18/09/2014 12:19, JiiPee wrote: |
Wouter van Ooijen <wouter@voti.nl>: Sep 18 03:01PM +0200 JiiPee schreef op 18-Sep-14 1:22 PM: > arrays anymore at all? > I mean if I am teaching C++ I would like to teach the correct way to do > things. Using a C arrays would teach wrong ways to program C++ , isn't it? That depends. If you want to teach how things work at the lowest level (as opposed to what one should use): when you get down to the implementation it is still C-style arrays and pointers. When programming in a resource-rich situation (for instance a PC) using the STL and other standard libraries is definitely a good idea. In a resource-constraint situation (for instance real-time work on a small micro-controller) using the same libraries might be a bad idea because they often use the heap (which you will likely not have), and have an unpredictable timing. (The *average* performance is generally very good, but that does not help at all in a strict real-time situation). Wouter van Ooijen (who happens to be teaching C++) |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 18 01:42AM +0100 > { 10 }, // Initialized into i > { 29.7f } // Initialized into f > }; Did you not just argue against one use of auto because you did not want the meaning to depend on a detail like the type of a constant? In that case, there is a chance the compiler will pick up such a mistake later, but that's not possible with this proposal. <snip> -- Ben. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 17 06:53PM -0700 On Wednesday, September 17, 2014 8:42:44 PM UTC-4, Ben Bacarisse wrote: > > }; > Did you not just argue against one use of auto because you did not want > the meaning to depend on a detail like the type of a constant? The constant in the auto reference had no definition to tie back to, and was entirely dependent upon its use in the function body for its type, allowing the error to potentially exist and be uncaught because it has no correlation due to auto. In this case the definition is provided in the union members. And while the possibility still exists of making a mistake and providing the incorrect form in the initializer, it would be less likely in my estimate because it would require the developer make two mistakes rather than just one (1-forgetting the proper declaration in the union, and 2-using an initializer form which could be readily translated into an existing type). It is still possible though. When you use unions there are some tradeoffs, and this is one of them (no direct typing, so the possibility of errors increases). > In that case, there is a chance the compiler will pick up such a > mistake later, but that's not possible with this proposal. > Ben. My personal preference would be that all initializers line up exactly, and if not then generate a compiler error so they must be explicitly cast to convey original intent. And in the case of there being some ambiguity, such as 5 being used as an initializer on a union which has both int and char members, and because the value 5 is within range of both and ambiguity exists, then they too should be explicitly cast -- unless they both translate into a compiled byte form which maps to the same memory location within the union, in which case it is automatically resolved by the peculiarities of the instance declaration, and the cast becomes unnecessary. Best regards, Rick C. Hodgin |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 18 01:33PM +0100 > was entirely dependent upon its use in the function body for its type, > allowing the error to potentially exist and be uncaught because it has > no correlation due to auto. Though, since the type of the function is affected, it might get caught later on in the compile. An error in the above can never be caught because the types are all correct. > make two mistakes rather than just one (1-forgetting the proper > declaration in the union, and 2-using an initializer form which could > be readily translated into an existing type). Maybe you did not get what I was referring to. An error (which can't be caught later on) can be introduced but a single character typo. Only one mistake is needed. <snip> > And in the case of there being some ambiguity, such as 5 being used as > an initializer on a union which has both int and char members, and > because the value 5 is within range of both and ambiguity exists, 5 is "in range" for a very large number of types (especially if the member has constructors defined). But this is C++ not C, and in C++ the programmer can differentiate between an int (5) and a char ('\5'). <snip> -- Ben. |
seeplus <gizmomaker@bigpond.com>: Sep 17 10:10PM -0700 On Thursday, September 18, 2014 7:58:44 AM UTC+10, Christopher Pisz wrote: > number of people saying things like, "strong evidence" and "overwhelming > evidence", but I myself have never in my entire lifetime actually seen > any evidence, and never will, because it is not observable. You have evolution right in front of your eyes (including the unrequired inside corners) with about 40 now useless vestigial parts still stuck on you, and you also have silly vestigial primate behaviours. e.g. You started as a foetus with a stupid tailbone ... for most people this thankfully reduces to your Coccyx now that you do not have to wrap it around a tree branch. Quite a few kids retain the actual monkey tail, requiring surgery. Men with tits. Now that is a major "design flaw" but does not look like going away for a long time. (Evolution == BAD. We would lose those good versions). Appendix. Used by our long ago ancestors for digestion. Slowly going away but appears to be >>yes!! evolving << to a smaller organ which may have uses in our current environment, doing a different job in the present day man's guts. Nasty Wisdom teeth. Useful for our stinking ancestor's diet, but quickly and painfully disappearing. Are you losing your little toenail? A lot of people are. Mine has just about gone. In a couple of generations that bit will be gone from humans, followed by the toe/s. I just do not shin up trees. You have many weird vestigial primate behaviours eg You get goose bumps. This really looks like we have evolved from those ugly common ancestors at the zoo, right? Or did that ADAM man just get stuck with these useless bits by a clumsy (pre 98) designer. Talk about haphazard edit and continue designing. |
Paavo Helde <myfirstname@osa.pri.ee>: Sep 17 05:46PM -0500 Robert Hutchings <rm.hutchings@gmail.com> wrote in > LOL. WELL, you guys were right. C++ is NOT fast enough for > "Ultra-HFT", in which FGPA modules are co-located with the exchanges. Of course we were right, as would have been anybody else who had taken those 30 seconds to type "HFT C++" into Google. Cheers Paavo |
Christopher Pisz <nospam@notanaddress.com>: Sep 17 06:33PM -0500 On 9/17/2014 3:36 PM, Robert Hutchings wrote: >> So ... why don't you check them out from the code repository? > Yes, I will. I work in a, shall we say, "controlled" environment, so I will have to "request" additional code from our Version Control Admin.... Sounds like a hassle. You do realize how in demand C++ programmers are in the job market, don't you? You've given us little insight into how your job functions, but if I don't have access to source control and you want me to figure out other people's code, whom contradict themselves in their comments (not uncommon) then piss off, because I can find another job in 2 day's time. |
Robert Hutchings <rm.hutchings@gmail.com>: Sep 17 08:49PM -0700 > want me to figure out other people's code, whom contradict themselves in > their comments (not uncommon) then piss off, because I can find another > job in 2 day's time. Yes, I tend to agree. Seems to happen frequently... |
Victor Bazarov <v.bazarov@comcast.invalid>: Sep 10 02:18PM -0400 On 9/10/2014 8:33 AM, Victor Bazarov wrote: >> I can think of a number of ways to do this, but I don't like any of >> them. What do you think is the most elegant way to do this? > It must be by means of std::copy. Or perhaps by means of one of c-tors. Standard string has a constructor from two input iterators (see 21.4.2/14), so if you can convert the positions into iterators, you could simply construct the string from them. V -- I do not respond to top-posted replies, please don't ask |
Victor Bazarov <v.bazarov@comcast.invalid>: Sep 11 12:05PM -0400 On 9/11/2014 11:58 AM, Christopher Pisz wrote: > std::vector<std::string> test = {"foo","bar"}; > I'd like to set up a static const at the top of my cpp to define a > collection of strings. a) Drop the '='. b) VC++ 2012 doesn't support that syntax. Get VC++ 2013. V -- I do not respond to top-posted replies, please don't ask |
Noob <nope@nono.com>: Sep 11 04:30PM -0300 Hi there. I'm performing my first experiments in C++ and I'm having a bit of trouble when trying put the definition of an operator overloading in a separate file. I understand the example is a bit silly but anyways. The following code when written in a single file will work and output the desired results: $cat foo_main.cpp #include <iostream> #include <array> template<typename T, std::size_t SIZE> std::array<T,SIZE> operator+(const std::array<T,SIZE>& a, const std::array<T,SIZE>& b) { std::array<T,SIZE> result; for(unsigned int i = 0; i < a.size(); ++i) { result[i] = a[i] + b[i]; } return result; } int main() { std::array<double, 10> arr1, arr2, arr3; for(unsigned int i = 0; i < arr1.size(); i++) { arr1[i] = i; arr2[i] = 2*i; } arr3 = arr1 + arr2; for(unsigned int i = 0; i < arr3.size(); ++i) { std::cout << arr3[i] << std::endl; } } $ g++ --version g++ (Debian 4.7.2-5) 4.7.2 $g++ -std=c++11 foo_main.cpp && ./a.out 0 3 6 9 12 15 18 21 24 27 Now let $cat foo.h #ifndef FOO_H_INCLUDED #define FOO_H_INCLUDED #include <array> template<typename T, std::size_t SIZE> std::array<T,SIZE> operator+(const std::array<T,SIZE>& a, const std::array<T,SIZE>& b); $ cat foo.cpp #include <array> #include "foo.h" template<typename T, std::size_t SIZE> std::array<T,SIZE> operator+(const std::array<T,SIZE>& a, const std::array<T,SIZE>& b) { std::array<T,SIZE> result; for(unsigned int i = 0; i < a.size(); ++i) { result[i] = a[i] + b[i]; } return result; } $ cat main_split.cpp #include "foo.h" #include <iostream> #include <array> int main() { std::array<double, 10> arr1, arr2, arr3; for(unsigned int i = 0; i < arr1.size(); i++) { arr1[i] = i; arr2[i] = 2*i; } arr3 = arr1 + arr2; for(unsigned int i = 0; i < arr3.size(); ++i) { std::cout << arr3[i] << std::endl; } } $g++ -std=c++11 main_split.cpp foo.cpp /tmp/cczMGm79.o: In function `main': main_split.cpp:(.text+0xdc): undefined reference to `std::array<double, 10ul> operator+<double, 10ul>(std::array<double, 10ul> const&, std::array<double, 10ul> const&)' collect2: error: ld returned 1 exit status I don't know what is the problem. I can compile a similar program declaring simple functions in separate files but not this particular case. Thanks in advance for any help. |
Juha Nieminen <nospam@thanks.invalid>: Sep 12 11:15AM > return > result; > } You need to instantiate it in *this* compilation unit with every type it's being used with anywhere else. Unfortunately since C++ does not support export templates (anymore), the compiler won't do it for you. You'll have to do it manually. If you want to do it like that, you need explicit instantiation (google for "template explicit insantiation"). However, the easiest way is to simply do it like you did in your first example, and put the implementation in the same header file where the declaration is. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
Noob <nope@nono.com>: Sep 11 06:03PM -0300 On 09/11/2014 05:12 PM, Paavo Helde wrote: > Actually, once there, better read through the whole FAQ. > Cheers > Paavo Thank you very much. There's -a lot- of useful information there. In my case, would you recommend me to move the definition of the template to the header file or to do the second solution shown here: http://www.parashift.com/c++-faq/separate-template-fn-defn-from-decl.html The former seems easy enough but I wouldn't like to make a habit of it if it happens to be a source of future complications. The latter solution implies in telling the compiler which instantiations I'll actually need (right?) but I'm not sure how to deal with it in my case without explicitly declaring a SIZE. Thanks again. |
Paavo Helde <myfirstname@osa.pri.ee>: Sep 12 01:17AM -0500 > In my case, would you recommend me to move the definition of the > template to the header file or to do the second solution shown here: > http://www.parashift.com/c++-faq/separate-template-fn-defn-from- decl.html > The former seems easy enough but I wouldn't like to make a habit > of it if it happens to be a source of future complications. [for the record: the second solution means explicit instantiation of templates in a single source file] In software development (and probably especially with C++) you will notice in time that complexity tends to increase "by itself" and fighting with the complexity is the most important thing to do. So the rule of thumb is to always prefer the simplest solution if possible, and here the first solution (putting all templates in header files) is definitely the simplest one and means least headaches to write and maintain. Many template libraries are actually header-only (including many parts of STL), so the compilers are ready to cope with them. Many people see that the first solution actually has several advantages: no need to guess which instantiations are required by the program, plus better optimization possibilities for the compiler (as the function definitions are visible inline). The only downside is that the compiling times might become larger, to fight this one can just keep the header files concsice and include them only in source files which actually need them. I would suggest to use the second solution (explicit instantiation in a source file) only when you are experienced enough to decide this is a better solution. Cheers Paavo |
Wouter van Ooijen <wouter@voti.nl>: Sep 12 10:05AM +0200 Paavo Helde schreef op 12-Sep-14 8:17 AM: > I would suggest to use the second solution (explicit instantiation in a > source file) only when you are experienced enough to decide this is a > better solution. That advice totally matches the third law of optimization: optimize only when you know there is a (speed or other) problem. (The first two law's are of course "don't" and "don't"). Wouter |
Martijn Lievaart <m@rtij.nl.invlalid>: Sep 12 09:21AM +0200 On Thu, 11 Sep 2014 15:04:01 -0700, kurt krueckeberg wrote: > managed pointer is the raw pointers are only used internally and never > exposed to clients. The class looks like this. shared_ptr<Node234> seems > like needless overhead? It would have masked the problem. Using unique_ptr<> would have exposed the problem more. > template<typename K> class Tree234 { > protected: ... > public: > Tree234() { root = nullptr; } > ~Tree234(); Where is operator=() ?? M4 |
Christopher Pisz <nospam@notanaddress.com>: Sep 11 05:18PM -0500 On 9/11/2014 5:12 PM, Mr Flibble wrote: >> only used internally and never exposed to clients. > No. > /Flibble I agree. Do not use shared pointers or any ref counting types just because they exist. I've encountered as many circular reference leaks as I have leaks from raw pointers. Either way, understand and verify when memory is allocated and when memory is released, even if using a ref counting or shared pointer, verify it actually got released. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 12 12:03PM +0100 On Fri, 12 Sep 2014 00:43:40 -0700 (PDT) > type traits only meant to be used for types from the STL and I should > simply define my own, even if their functionality is basically the > same? This is an interesting question. On whether you can do it, §17.6.4.2.1/1 of the C++11 standard states that: "The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited." On 'is_integral' and 'is_arithmetic' in particular, §20.9.2/1 (which includes those type trait structs) provides that "The behavior of a program that adds specializations for any of the class templates defined in this subclause is undefined unless otherwise specified." This presupposes that there are some type traits amongst these which are specified elsewhere in the standard as permitted to be specialized, but I have to say I have not traced what they are, and I should be interested if you find any. However, they do not appear to include the ones in which you are interested. Presumably the thinking behind this is that there should never normally be a need to specialize 'is_integral', 'is_arithmetic' or any of the other primary or composite type categories in §20.9.4.1 and §20.9.4.2 for user defined types, because these are features that by language definition only a built-in type can possess. A type is integral if it meets the definition in §3.9.1/7. It is arithmetic if it meets the definition in §3.9.1/8. I should have thought it would be less confusing to users of your library if you provided your own type trait structs for extended arithmetic types. And I would think it less confusing not to provide your own type trait which suggests that an extended arithmetic type is a fundamental type unless in fact it happens to be a typedef for a fundamental type according to the language definition. Chris |
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