Why?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Noah Roberts

    Why?

    Many toolkit authors create their own string types instead of using
    std::string. This includes the likes of Qt and FOX. My question, and
    perhaps it is not topical, is why would people do this? They also don't
    provide conversion functions to/from std::string! This makes it so you
    are always converting to/from std::string yourself to communicate with
    these APIs. Very annoying.

    NR

  • wogston

    #2
    Re: Why?

    [color=blue]
    > Many toolkit authors create their own string types instead of using
    > std::string. This includes the likes of Qt and FOX. My question, and
    > perhaps it is not topical, is why would people do this? They also don't
    > provide conversion functions to/from std::string! This makes it so you
    > are always converting to/from std::string yourself to communicate with
    > these APIs. Very annoying.[/color]

    std::string isn't one of the better parts of the standard library, IMHO.
    Speaking of which, I started writing prototype of linked-list using Knuth's
    single-pointer double-linked list technique, I decided to implement it as
    std::list<> -lookalike, here's URL for work-in-process version (it won't
    compile w/o metatype.hpp -header, which defines couple of templates and
    types, and macros, but the idea should be fairly clear to read ;)




    ... and "screenshot " of a small test:




    I haven't really kept thread safety in mind, just want to try out the
    concept.. so far it appears to be a solid idea. Also get iterator,
    const_iterator, reverse_iterato r and const_reverse_i terator with same
    template as by-product, less maintenance overhead. I don't throw exceptions
    either, where std::list might (I haven't looked at the problem from this
    angle), so that could explain the speed differences. I am testing in release
    build and the count is 200K in the list.jpg.

    There are a few design choises I am not completely happy about, but they are
    trade-offs between speed in different areas. First Issue:

    the ::begin(), ::end(), etc. return iterators of various types, it would be
    advantageous to cache the step values so that they don't need to be
    re-computed, however, the re-computation is only two bitwise xor's so I
    think that optimization would be defeated when maintenance overhead would
    attack all other more frequently called methods. This is "problem" only in
    situation such as this:

    list<int>::iter ator i = v.begin();
    for ( ; i != v.end(); ++i )
    ;

    So it would be advantageous to cache the v.end(), unless we write into the
    container.. etc..

    Second Issue is that -- operator must step twice, first to get into the next
    node, to get new source.. then step over current node to reversed direction,
    so it's two xor's instead of one. Could cache the source -and- destination
    pointers, and when --'ing, step to get "new destination", write current to
    temp, write destination into current, and write current to source.

    But again, the maintenance overhead would kick in, and the backwards
    stepping is still virtually same speed as stepping "ahead" (++), so prefer
    it the way it is. But that did bear mentioning. :)

    "ahead" (++) and "backwards" (--) are relative concept in this
    implementation, as the direction is determined by the current state of the
    iterator (it cannot be switched in-flight, only when iterator is created,
    this way the reverse_iterato r stays reverse_iterato r and iterator remains
    iterator regardless of what the client does. I will propably add bool
    template parameter to formally enforce the difference between the two, so
    don't need criticism for that-- consider it being in the TODO -list.

    I hope I got the semantics nailed down correctly, criticism is welcome, you
    seem ideal candidate to flame the implementation: :) :)

    -w


    Comment

    • Jon Bell

      #3
      Re: Why?

      In article <vq0l84tl6docd@ corp.supernews. com>,
      Noah Roberts <nroberts@donte mailme.com> wrote:[color=blue]
      >Many toolkit authors create their own string types instead of using
      >std::string. This includes the likes of Qt and FOX. My question, and
      >perhaps it is not topical, is why would people do this?[/color]

      In some cases at least, it's because the toolkit was written before
      std::string arrived as part of the C++ standard in 1998 or thereabouts.
      If it ain't broke, don't fix it...

      --
      Jon Bell <jtbellap8@pres by.edu> Presbyterian College
      Dept. of Physics and Computer Science Clinton, South Carolina USA

      Comment

      • Noah Roberts

        #4
        Re: Why?

        Jon Bell wrote:[color=blue]
        > In article <vq0l84tl6docd@ corp.supernews. com>,
        > Noah Roberts <nroberts@donte mailme.com> wrote:
        >[color=green]
        >>Many toolkit authors create their own string types instead of using
        >>std::string . This includes the likes of Qt and FOX. My question, and
        >>perhaps it is not topical, is why would people do this?[/color]
        >
        >
        > In some cases at least, it's because the toolkit was written before
        > std::string arrived as part of the C++ standard in 1998 or thereabouts.
        > If it ain't broke, don't fix it...
        >[/color]
        Well in my opinion, if they don't need some sort of extra functionality,
        it is broke. An addon toolkit should make use of existing, standard
        features, even if those features are newer; that would be part of
        maintenence. Even if there is needed functionality they should add the
        copy constructors and other necissities to make it so I can pass a
        std::string to any function that expects the non-standard string...and
        visa versa. In my opinion this sort of thing should not be:

        string myString(instan ce.getString(). getText());
        function(myStri ng.c_str());

        Too many conversions are happening here. From their string to char[]
        from char[] to string from string back to char[] from char[] to their
        string (keep in mind that the std::string is probably something I am
        using beyond the simple example above). Even if all of those
        conversions are necissary, a decent API would hide them.

        string myString = instance.getStr ing();
        function(myStri ng);

        This is just a major pet-peeve of mine.
        --
        Noah Roberts
        - "If you are not outraged, you are not paying attention."

        Comment

        • Noah Roberts

          #5
          Re: Why?

          wogston wrote:
          [color=blue]
          > I hope I got the semantics nailed down correctly, criticism is welcome, you
          > seem ideal candidate to flame the implementation: :) :)[/color]

          I don't have time to play right now, but when I do I will look it over.
          I am currently studying that section of knuth so...

          Right off I would say, have you tested it with the functions in
          <algorithm>? If your list works with those, has an interface similar to
          list<>, and can accept something like this:

          list<int> function();

          yourlist<int> myList = function();

          then that seems like a very good implementation of a third party add on.

          If, on the other hand, it works completely different, does not compute
          with std::list, then no matter how good it is I probably won't want to
          relearn.

          --
          Noah Roberts
          - "If you are not outraged, you are not paying attention."

          Comment

          • wogston

            #6
            Re: Why?

            > Right off I would say, have you tested it with the functions in[color=blue]
            > <algorithm>? If your list works with those, has an interface similar to
            > list<>, and can accept something like this:[/color]

            The goal (at first, atleast) wasn't do anything particular at all, except
            toy around implementing the Knuth -technique as container with std::list
            semantics. I have at this point only getting the semantics nailed down, so
            that results are 'as expected', just thought to share what have so far.

            [color=blue]
            > If, on the other hand, it works completely different, does not compute
            > with std::list, then no matter how good it is I probably won't want to
            > relearn.[/color]

            The practical problem is, that the implementation is in different scope than
            std:: , generally I have the impression 3rd party libraries shouldn't be in
            the std:: namespace. This will create incompatibility for certain, even if
            methods are same, even if the semantics and behaviour are precisely the
            same.

            Basicly, I should inherit from those std types which are required for gluing
            everything together. For instance, if some algorithm expects iterator, I
            should use compatible types so that could actually go and pass my iterators
            as arguments. The std::sort() in <algorithm> for example takes happily my
            iterators as input (with the compiler I am using), but I am not sure because
            it that my iterators have the same methods, definitely it isn't because they
            are derived from same base class.

            I don't recommend using the code, I posted it out as item-of-interest (to
            some, not necessarily to everyone!), even if only small minority. I'll try
            to make it as compatible as possible within the limitations of
            scope/namespace issues as possible to humor myself only. It's not because I
            expect re-inventing wheel to be productive.

            I'm also aware that the speed differences experienced can be remedied by
            writing custom allocator for std::list, and in this context the caching
            strategy implemented in core::list<> is irrelevant as far as performance is
            metric. Typical std implementation, atleast I hope so, is more exception and
            threading aware and so on.

            So basicly I am just doing this for fun and educational value, and in the
            process I hope to learn more of the standard library than I otherwise would
            in much longer period of "merely using it"-- as far as programming goes, I
            am one of those "self-learned" types without formal education, so I do
            things and find out and try to understand things 'right'. I found a bug in
            MSDN, infact, while I used it as reference... someone look up ::rbegin() and
            ::rend() for std::list! Is that correct!? Looks like it isn't! The
            Dinkumware implementation works correctly, ofcourse, so it seems only to be
            a documentation bug only.


            -w


            Comment

            • wogston

              #7
              Re: Why?

              > as arguments. The std::sort() in <algorithm> for example takes happily my[color=blue]
              > iterators as input (with the compiler I am using), but I am not sure[/color]
              because[color=blue]
              > it that my iterators have the same methods, definitely it isn't because[/color]
              they

              ~clarification: for core::vector<>, occured after posting that someone might
              think I meant core::list<>, ..

              -w


              Comment

              • Lasse Skyum

                #8
                Re: Why?

                I found my own string-class to be way more "handy" than std::string... it
                can cast itself to char* without c_str and basic types (int, float,
                double...) can be added to it. It has lower/upper-case and substring
                functions... need I say more?

                --
                Lasse


                Comment

                • Ahti Legonkov

                  #9
                  Re: Why?

                  Noah Roberts wrote:[color=blue]
                  > ...
                  > In my opinion this sort of thing should not be:
                  >
                  > string myString(instan ce.getString(). getText());
                  > function(myStri ng.c_str());
                  >
                  > Too many conversions are happening here. From their string to char[]
                  > from char[] to string from string back to char[] from char[] to their
                  > string (keep in mind that the std::string is probably something I am
                  > using beyond the simple example above). Even if all of those
                  > conversions are necissary, a decent API would hide them.
                  >
                  > string myString = instance.getStr ing();
                  > function(myStri ng);
                  >[/color]
                  You could write your own string class that does the conversions for you.
                  Something like this:

                  class MyString
                  {
                  public:
                  MyString(std::s tring const& s);
                  MyString(QStrin g const& s);
                  MyString(MyStri ng const& s);

                  MyString& operator=(std:: string const& s);
                  MyString& operator=(QStri ng const& s);
                  MyString& operator=(MyStr ing const& s);

                  operator std::string();
                  operator QString();
                  operator char*();
                  };

                  Using this kind of string class you would not have to do it as in your
                  example but like so:

                  MyString myString(instan ce.getString()) ;
                  function(myStri ng);

                  --
                  Ahti Legonkov

                  Comment

                  • wogston

                    #10
                    Re: Why?

                    > I found my own string-class to be way more "handy" than std::string... it[color=blue]
                    > can cast itself to char* without c_str and basic types (int, float,
                    > double...) can be added to it. It has lower/upper-case and substring
                    > functions... need I say more?[/color]

                    :) I do the same :)

                    -w


                    Comment

                    • Jerry Coffin

                      #11
                      Re: Why?

                      In article <3fa0f973$0$699 91$edfadb0f@dre ad12.news.tele. dk>, "Lasse
                      Skyum" <lskyum(AT)mail .dk> says...[color=blue]
                      > I found my own string-class to be way more "handy" than std::string... it
                      > can cast itself to char* without c_str and basic types (int, float,
                      > double...) can be added to it. It has lower/upper-case and substring
                      > functions... need I say more?[/color]

                      I think it's safe to say that nearly everybody who's written C++ for
                      more than a few months has done this at least once. Unfortunately,
                      while handy at first, those implicit conversions tend to cause problems
                      in the long run.

                      --
                      Later,
                      Jerry.

                      The universe is a figment of its own imagination.

                      Comment

                      • Rolf Magnus

                        #12
                        Re: Why?

                        Noah Roberts wrote:
                        [color=blue]
                        > Jon Bell wrote:[color=green]
                        >> In article <vq0l84tl6docd@ corp.supernews. com>,
                        >> Noah Roberts <nroberts@donte mailme.com> wrote:
                        >>[color=darkred]
                        >>>Many toolkit authors create their own string types instead of using
                        >>>std::strin g. This includes the likes of Qt and FOX. My question,
                        >>>and perhaps it is not topical, is why would people do this?[/color]
                        >>
                        >>
                        >> In some cases at least, it's because the toolkit was written before
                        >> std::string arrived as part of the C++ standard in 1998 or
                        >> thereabouts. If it ain't broke, don't fix it...
                        >>[/color]
                        > Well in my opinion, if they don't need some sort of extra
                        > functionality, it is broke. An addon toolkit should make use of
                        > existing, standard features, even if those features are newer; that
                        > would be part of maintenence.[/color]

                        No. If write programs using that library and want to update to a new
                        version of the lib, you'd need to rewrite major parts of the program.
                        Just think about the need to replace all the strings used and change
                        the code to use another string class. Also, for the Qt example,
                        std::string is missing some important things. QString has full unicode
                        support on every platform that is supported by Qt, and you can convert
                        between character sets. std::string or std::wstring doesn't even define
                        any character set. Also, Qt was made for many platforms which might
                        even now not have a full implementation of the standard library (some
                        embedded platforms AFAIK), and so Qt offers something independant of
                        it.
                        [color=blue]
                        > Even if there is needed functionality
                        > they should add the copy constructors and other necissities to make it
                        > so I can pass a std::string to any function that expects the
                        > non-standard string...and visa versa.[/color]

                        Qt does that.
                        [color=blue]
                        > In my opinion this sort of thing should not be:
                        >
                        > string myString(instan ce.getString(). getText());
                        > function(myStri ng.c_str());
                        >
                        > Too many conversions are happening here. From their string to char[][/color]

                        Which also would mean a conversion of the character set down to an 8bit
                        char set.
                        [color=blue]
                        > from char[] to string from string back to char[] from char[] to their
                        > string (keep in mind that the std::string is probably something I am
                        > using beyond the simple example above). Even if all of those
                        > conversions are necissary, a decent API would hide them.
                        >
                        > string myString = instance.getStr ing();
                        > function(myStri ng);[/color]

                        How would you specify the character set for the intermediate 8 bit
                        characters?
                        [color=blue]
                        > This is just a major pet-peeve of mine.[/color]

                        Comment

                        • lilburne

                          #13
                          Re: Why?

                          Noah Roberts wrote:
                          [color=blue]
                          >
                          > Well in my opinion, if they don't need some sort of extra functionality,
                          > it is broke. An addon toolkit should make use of existing, standard
                          > features, even if those features are newer; that would be part of
                          > maintenence.[/color]

                          Some of our software engineers maintain that unless a line
                          of code needs changing to fix a bug, or provide additional
                          functionality then you don't change it.

                          You don't change the variable or argument names, you don't
                          remove redundant whitespace, you don't rearrange the
                          functions in the source file so that they are in
                          alphabetical order, you don't reformat it to conform to
                          current coding standards, and you don't change the classes
                          it operates on to update them to the latest and greatest
                          alternatives.

                          All such changes are gratuitous, unless properly planned,
                          budgeted and agreed upon, and have a code change document
                          specifying why the work is being undertaken.

                          Comment

                          • Calum

                            #14
                            Re: Why?

                            Noah Roberts wrote:[color=blue]
                            > Many toolkit authors create their own string types instead of using
                            > std::string. This includes the likes of Qt and FOX. My question, and
                            > perhaps it is not topical, is why would people do this? They also don't
                            > provide conversion functions to/from std::string! This makes it so you
                            > are always converting to/from std::string yourself to communicate with
                            > these APIs. Very annoying.[/color]

                            Many of these toolkits were started before a consistently implemented
                            std::basic_stri ng, or even templates were available. I think every
                            toolkit writer should now upgrade their toolkits so their own string
                            classes derive from std::string. This would be better for sharing
                            strings between different toolkits.

                            std::basic_stri ng isn't great - I hate stringstreams - just so slow.
                            But that's the standard so we have to live with it. I've written a nice
                            format_string() that does the same as sprintf() roughly, and a
                            compatible fixed_string<in t N, class C> that is a safe version of C[N]
                            that prevents overflow.

                            Calum

                            Comment

                            Working...