Thread: Though implementation problem

  1. #31
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Elysia View Post
    It's funny how you agree now. Functions that are generic and can do a lot of things are good. Very good. You agree.
    Yet for my classes, I'd rather write high-level wrappers and put them as members. The members are merely wrappers for the generic function. You agree wrappers are good.
    Had you actually made you position clear from the beginning (wrapping generic functions to provide cleaner interfaces) we could have avoided this whole time-waster.

    To further add, I have never been against algorithms or powerful functions such as a generic one as you show, but the problem comes when you must use those in your code instead of higher level wrappers for simple functionality.
    That's not really at all what you stated. You basically stated that the standard library has been ruined by generics.

  2. #32
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    That is a documentation problem, not a design problem.
    Pretty much. But you know that some won't do it right, anyway. It's just sad.

    I think that the correct approach is to put everything in the namespace, unless you want to emphasize the separation from the core interface of the class. Obviously, we are not back to plain C since the namespace mechanism is at work to avoid name collision.
    I think namespaces are great, I really do. But they do not evolve code into something higher. What's good with classes? How about they can easily manage an internal state without littering around globals, how they can overload operators and can easily take care of their own resource management via constructors, copy constructors and destructors? The compiler will call them automatically for us, instead of we having to remember to call cleanup functions.
    Namespaces do not contribute to that very much, I'm afraid, so without classes, it's like it's back to the good old C days.

    So you would rather that std::string be a polymorphic base class? OOP really is about abstraction, encapsulation, inheritance and polymorphism via objects. OOP is not about classes and whether functions are member functions, static member functions, or non-member functions.
    Well, then I don't know if there's a good work for putting members inside the class instead of outside :/

    I think that is what you should do: provide wrappers to wrap the application of a generic algorithm to provide specific functionality that can be more easily used. That way, clients can enjoy both the flexibility of the generic algorithm and the quick access to the specific functionality. I believe this has been mentioned before.
    Then here's my beef with the standard library: why are there still too much relying on algorithms? Is it simply lack of time or due to the committee's lack of money?

    [QUOTE=brewbuck;752171]Had you actually made you position clear from the beginning (wrapping generic functions to provide cleaner interfaces) we could have avoided this whole time-waster.
    True, true. Lack of communication. But I'm glad I can learn to agree with you.

    That's not really at all what you stated. You basically stated that the standard library has been ruined by generics.
    This is because I see algorithms, free functions and overcomplication everywhere.
    I expect a replace function to seek and replace every instance of X with Y, but that's not what std::string::replace does and it frustrates me because these classes never work in a way I expect and need.
    Last edited by Elysia; 05-11-2008 at 11:59 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #33
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What's good with classes? How about they can easily manage an internal state without littering around globals, how they can overload operators and can easily take care of their own resource management via constructors, copy constructors and destructors? The compiler will call them automatically for us, instead of we having to remember to call cleanup functions.
    Namespaces do not contribute to that very much, I'm afraid, so without classes, it's like it's back to the good old C days.
    Classes versus namespaces is not a zero sum game. That classes can provide functionality that namespaces cannot do not point to a deficiency in namespaces, but to the fact that they have different use cases. I am not saying: prefer namespaces to classes. I am saying: use namespaces and classes (and free functions) appropriately.

    Then here's my beef with the standard library: why are there still too much relying on algorithms? Is it simply lack of time or due to the committee's lack of money?
    The reason is that the standard library is designed to cater to the users of a language, not the programmers of any particular application domain. The other reason is that design by committee often leads to half-way decisions due to compromises
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #34
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Elysia View Post
    This is because I see algorithms, free functions and overcomplication everywhere.
    I expect a replace function to seek and replace every instance of X with Y, but that's not what std::string::replace does and it frustrates me because these classes never work in a way I expect and need.
    Odd that you pick this example, since std::replace() (the fully generic version) would actually do what you're talking about. So this is an instance of a class simply not doing what you want it to do, not some disadvantage to generics.

  5. #35
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    Classes versus namespaces is not a zero sum game. That classes can provide functionality that namespaces cannot do not point to a deficiency in namespaces, but to the fact that they have different use cases. I am not saying: prefer namespaces to classes. I am saying: use namespaces and classes (and free functions) appropriately.
    That just boils down to to having the functions split. Some in the namespace, some in the class, which is what I wanted to avoid in the first place :/

    Quote Originally Posted by brewbuck View Post
    Odd that you pick this example, since std::replace() (the fully generic version) would actually do what you're talking about. So this is an instance of a class simply not doing what you want it to do, not some disadvantage to generics.
    True, obviously nothing at fault with the generics, simply lack of higher-level functions within the class, as you would expect when there's a fully generic function in the std namespace.
    I just looked over the basic_string documentation in MSDN and I can tell it's incredibly confusing.
    The standard library truly needs more higher-level functions...


    But I cannot help but seem that the original question has yet to be answered...
    Or the second one of splitting the implementation...
    Wrappers are important...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #36
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Odd that you pick this example, since std::replace() (the fully generic version) would actually do what you're talking about. So this is an instance of a class simply not doing what you want it to do, not some disadvantage to generics.
    To do Elysia justice, I don't think std::replace can do that (replacing substring for string), it can replace a character for another character. However, boost's string algorithms can do that and much more (alas, with free functions).

    I expect a replace function to seek and replace every instance of X with Y, but that's not what std::string::replace does and it frustrates me because these classes never work in a way I expect and need.
    But what if I actually want to replace a range for another?

    As to the original question, can't you do something like this?
    Code:
    #include <iostream>
    
    template <class T>
    void convert(T n, T& m)
    {
        std::cout << "no conversion really\n";
        m = n;
    }
    
    void convert( int n, float& f)
    {
        std::cout << "converting int into float\n";
        f = n;
    }
    
    void convert( float n, int& i)
    {
        std::cout << "converting float into int\n";
        i = static_cast<int>(n);
    }
    
    template <class T>
    struct Number
    {
        T value;
        Number(T t): value(t) {}
        Number<int> to_int() const { Number<int> n(0); convert(value, n.value); return n; }
        Number<float> to_float() const { Number<float> f(0.0); convert(value, f.value); return f; }
    };
    
    int main()
    {
        Number<int> n1(10), n2(12);
        Number<float> f1(1.1), f2(2.2);
        n1 = n2.to_int();
        n2 = f1.to_int();
        f1 = f2.to_float();
        f2 = n2.to_float();
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #37
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by anon View Post
    But what if I actually want to replace a range for another?
    Oh sure, it's not like I'm saying it's bad or anything, but I never find functionality I need or expect.

    As to the original question, can't you do something like this?
    Well, I was just looking into making something like:

    Code:
    Strings::CTmplStringBase< char, Strings::StrTraits<char> > CharStr;
    Strings::CTmplStringBase< wchar_t, Strings::StrTraits<wchar_t> > WCharStr;
    CharStr.ToUTF16(); // OK, source is ANSI
    WCharStr.ToANSI(); // OK, source is UTF16
    CharStr.ToANSI(); // Illegal, no such member function
    WCharStr.ToUTF16(); // Illegal, no such member function
    I was trying out template specialization to do it, but as you see, I ran into trouble...
    Since the definition returns the string class (which inherits from the definition), I must use a pointer or reference.
    And secondly, the implementation also uses the class, further adding to the problem. I haven't found a way to separate the implementation from the definition (since the definition is in itself a specialized template class). Which was all discussed in the first post.

    It would be cool, but otherwise I have to go for adding both members to the generic template and probably throw an error if the conversion can't be done.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #38
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Long<>Short: The same technique used by the Boost adder operator you are using can be used to do what you want. Instead of specializing on the element type of the string/container you need to specialize on the type of string. It is rather simple. The problem with this is that it changes the interface making the two/infinitely-many base classes incompatible. If you go this root you must separate your normal interface and your extended interface else it would not be very "OO" would it?

    Also: 'ToUTF16' and 'ToANSI' are truly terrible names--for one there is character encoding called ANSI.

    And you still fall into the design problem because of your misunderstanding of "OO" and silly prejudice. You argue that every function anyone might find useful should be part of the class--even if that means extending the class through inheritance, and at least in part you claim to argue this because "everyone will know where to look", but we recently discovered that really you only argue for this kind of thing because the syntax is sexy to your mind. The problem with this kind of logic is evident: it necessarily leads to innumerable classes with infinitely large interfaces exhibiting mutually incompatible behavior. Such a catastrophe of interface design invariably leads to unmaintainable crossing; such source is by definition not "OO".

    Soma

  9. #39
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by phantomotap View Post
    Long<>Short: The same technique used by the Boost adder operator you are using can be used to do what you want. Instead of specializing on the element type of the string/container you need to specialize on the type of string. It is rather simple. The problem with this is that it changes the interface making the two/infinitely-many base classes incompatible. If you go this root you must separate your normal interface and your extended interface else it would not be very "OO" would it?
    Well, OO or not, what's good about C++ is that you aren't limited to one paradigm.

    Also: 'ToUTF16' and 'ToANSI' are truly terrible names--for one there is no character encoding called ANSI.
    Did you forget a "no" keyword in there?
    If they are terrible names, what would you suggest?

    And you still fall into the design problem because of your misunderstanding of "OO" and silly prejudice. You argue that every function anyone might find useful should be part of the class...
    If it part of what the object does, then yes. Neatly organized.

    --even if that means extending the class through inheritance, and at least in part you claim to argue this because "everyone will know where to look", but we recently discovered that really you only argue for this kind of thing because the syntax is sexy to your mind.
    You might call it a bit of both.

    The problem with this kind of logic is evident: it necessarily leads to innumerable classes with infinitely large interfaces exhibiting mutually incompatible behavior. Such a catastrophe of interface design invariably leads to unmaintainable crossing; such source is by definition not "OO".
    This one strikes me odd, however. If classes cannot be extended indefinitely, how do OO people do it? Create several classes built around the same thing?


    But come on, give me some slack here. C++ isn't just straight forward. I'm testing methods and ways of doing things. Without experimenting, you won't learn anything.
    Surely there must be other people who do the same.
    Last edited by Elysia; 05-12-2008 at 02:19 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #40
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If it part of what the object does, then yes. Neatly organized.
    By introducing so many member functions, you reduce encapsulation. You do not gain on organization since non-member non-friend functions organized in the same namespace also results in neat organization. You also do not gain on abstraction since the class' minimal but complete interface models the domain sufficiently.

    This one strikes me odd, however. If classes cannot be extended indefinitely, how do OO people do it? Create several classes built around the same thing?
    The non-member non-friend functions that we have mentioned is one way, though in some languages they would be static member functions of an auxiliary class instead. Composition (e.g., with the decorator pattern) is another way. Of course, it may be the case that inheritance is appropriate, so it depends on the situation.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #41
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    By introducing so many member functions, you reduce encapsulation. You do not gain on organization since non-member non-friend functions organized in the same namespace also results in neat organization. You also do not gain on abstraction since the class' minimal but complete interface models the domain sufficiently.
    But there are ways around that. One is to create a free member function and create a wrapper as a member.

    The non-member non-friend functions that we have mentioned is one way, though in some languages they would be static member functions of an auxiliary class instead. Composition (e.g., with the decorator pattern) is another way. Of course, it may be the case that inheritance is appropriate, so it depends on the situation.
    So another way might to break up the class into several smaller classes where the interface is easier to manage and then simply inherit them into one big class? That sounds like it would squash the problems with big classes, yet let you use a big class.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #42
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    1. A program that is not extensible has a polynomial (e.g. n-squared) amount of time required to add a new feature. For each new feature you must also reimplement many existing components.
    2. A program that is extensible has a linear amount of time required to add a new feature. For each new feature you add you must implement it for each class.
    3. A program that contains reusable code requires a sub-linear (possibly constant) amount of time required to add a new feature. You implement the feature once and you're done - it works with almost every other component automatically.

    That's knowledge I gained form a course some time ago.

    The algorithms provided by the std library for example, put programming in the last category. You however, are at best always designing your programs aiming at option 2. As your program size doubles, the amount of work required to add a new feature roughly doubles. It may seem good to you now because it's much better than option 1. However, continue the way you're going and you'll never succeed at a large scale project.
    I work on a project with over half a million lines of code, every day. If we were only aiming for an extensible program then we wouldn't have gotten this far, and still be able to maintain it easily.
    You've got to see the big picture.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #43
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Wait, some of that seems contradicting.
    Option 2 means adding higher level functionality to your program. It takes roughly double the time. But they are, I guess, mostly free functions, as to be able to reuse code for other classes.

    Then I take it option 3 means you go the way of the standard library. Lots of low level functionality and algorithms. Much code reuse, but little programmer friendly, so it becomes hard to maintain.

    Only creating member functions will lead to option 1.

    So the aim is to go for option 2 - try to put as much functionality as you can as free functions, and wrap those via higher level functions possible. This might mean high level free function or high level member functions, depending on what is appropriate.
    Since classes can be come a chore when growing bigger, it is best to put functionality outside and create wrappers inside, and possible make several smaller classes and derive them into one bigger class, if you want.

    The picture I'm seeing is that it might just give the best of both worlds with as little sacrifice as possible (there will, of course, be no perfect solution, but as I see it, it's a small sacrifice that won't do that much harm).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #44
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One is to create a free member function and create a wrapper as a member.
    I assume that by "free member function" you mean "free function". A member function wrapper still has access to the class internals, and can cease to be a wrapper after maintenance. In other words, you do not increase encapsulation by providing syntactic sugar.

    So another way might to break up the class into several smaller classes where the interface is easier to manage and then simply inherit them into one big class? That sounds like it would squash the problems with big classes, yet let you use a big class.
    Are you referring to one approach used in Java: the use of multiple inheritance with pure interfaces? If so, I think that this is less useful in C++ due to the template mechanism, particularly so when the C++0x concept of a concept comes into play.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #45
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    I assume that by "free member function" you mean "free function". A member function wrapper still has access to the class internals, and can cease to be a wrapper after maintenance. In other words, you do not increase encapsulation by providing syntactic sugar.
    Yes, I meant free function, of course.
    But if the wrapper member starts to divulge from the free function, it means the free function must be updated, as well, since seeing as if there was no member from the beginning the functionality that is required simply doesn't exist.

    The concept of free functions is to increase encapsulation and to protect the class against changes, and to increase code reuse...
    So what are the purposes of member functions? To provide the functionality that the free members lack?

    Are you referring to one approach used in Java: the use of multiple inheritance with pure interfaces? If so, I think that this is less useful in C++ due to the template mechanism, particularly so when the C++0x concept of a concept comes into play.
    Yes, the java method... but C++0x seems to add some more things that would require a little reschooling when it comes out and is supported I think.
    I don't know very much about the feature, paradigms or the like that will show up in C++0x.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  2. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  3. implementation file
    By bejiz in forum C++ Programming
    Replies: 5
    Last Post: 11-28-2005, 01:59 AM
  4. Replies: 5
    Last Post: 11-07-2005, 11:34 PM
  5. Memory Problem - I think...
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 10-24-2001, 12:14 PM