Thread: Storing functors?

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Storing functors?

    I seem to have hit a bit of a snag again.
    I wanted to make it possible to couple (I think that's the right word?) my input class a little more, as to make it the answer itself, as well as the inputter of that answer.
    To do that, I wanted to add verification as part of the process, as well as the possibility of a custom conversion std::string -> T.
    Basically that would mean taking a functor in the constructor and storing it for later when the ask member function is called. But how would we do this? I cannot store it inside the class if I do not know the type... and to know the type, I would have to include it for the class template, which means explicitly specifying it which defeats the entire purpose...

    Code:
    template<typename Type, typename CharT = StrType_t,
             template<typename> class ValidateFunctor = ValidateDefault,
             template<typename> class Traits = InputTraits
      > class CInput
    The red part highlights the unknown. Taking a class functor is not really what I want. I basically want to make it work with lambda expressions that is coming with C++0x. A sample use of how to use the class would be:

    Code:
    Stuff::Cinput<int> KeyLength(
        "Enter length of the key", [&]
        {
            cout << "Error. Invalid key.";
        },
        [&] (int Key) -> bool
        {
            return (Key >= 2 && Key <= 5);
        });
    An example of how I would like an implementation is:
    Code:
    		void ask(Type& Answer)
    		{
    			Answer = m_Converter();
    			if (! m_Validater(Answer) )
    				m_Error();
    		}
    I simply lack the know-how.
    Last edited by Elysia; 11-12-2008 at 06:15 AM. Reason: Make more readable
    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.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Have you at least considered reworking your design to use inheritance? That way if the programmer has special needs, he can make a derived type, and you can provide whatever you want. Seems more clear than some template wank, IMHO. Probably not being helpful here, but needed to point that out.

    This came to mind since in any given type of input class you'd have common members like convert and validate.
    Last edited by whiteflags; 11-11-2008 at 12:36 PM.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Any design changes or help is welcome. I like to make things as flexible and easy as possible.
    Perhaps the conversion bit can be made through a virtual function, but the validation part wouldn't really be plausible, I think, since you want to hand off the validation to the class and have many different types of validation. Deriving the classes and overriding a validation function seems like a lot of work and a poor solution.

    It would be cool if it could work with the new C++0x features.
    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.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You could just take a std::function<bool (Type)>. (One of C++0x std::function, TR1 std::tr1::function, and boost::function.)

    Or you could rewrite the whole thing as a function instead of an object:
    Code:
    template <typename Type, typename Char, typename Validator>
    Type readInput(const Char* prompt, const Char* error, Validator v)
    {
      typedef input_traits<Char> it;
      it::outs << prompt;
      Type t;
      it::ins >> t;
      while(!it::ins || !v(t)) {
        reset(it::ins); // clears and discards all available input
        it::outs << error << prompt;
        it::ins >> t;
      }
      return t;
    }
    Since apparently your CInput is now one-shot, I feel that a class is inappropriate anyway.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Perhaps the conversion bit can be made through a virtual function, but the validation part wouldn't really be plausible, I think, since you want to hand off the validation to the class and have many different types of validation.
    That didn't seem like part of the specified problem when you first introduced this class in another thread. If part of your goal is simply to remove the tedium in validating and converting built-ins, you can do that easily, and it should greatly assist others in writing the I/O parts of most projects.

    IMO, it is just as important that some of the methods in your class don't validate, or it could be a reason to keep the validation method protected by the class. Presumably, you would just specialize the template for built-ins before you ship the library. Their validation algorithms could be coded in terms of stringstreams and the manipulators in <iomanip>, for example, if you are feeling especially lazy. Users of your class could then build operator>> for their class in terms of these. Now they can optionally use whatever "grab it" function you provide in your interface without much cause for concern. Is that an acceptable use of your class?

    I imagine that validate would only be overriden where it couldn't be avoided anyway, but the highway to hell is paved with good intentions. And I'll take this edit to agree with cornedbee, the class doesn't really solve a problem anymore.
    Last edited by whiteflags; 11-11-2008 at 03:52 PM.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    You could just take a std::function<bool (Type)>. (One of C++0x std::function, TR1 std::tr1::function, and boost::function.)

    Or you could rewrite the whole thing as a function instead of an object:
    Code:
    template <typename Type, typename Char, typename Validator>
    Type readInput(const Char* prompt, const Char* error, Validator v)
    {
      typedef input_traits<Char> it;
      it::outs << prompt;
      Type t;
      it::ins >> t;
      while(!it::ins || !v(t)) {
        reset(it::ins); // clears and discards all available input
        it::outs << error << prompt;
        it::ins >> t;
      }
      return t;
    }
    Since apparently your CInput is now one-shot, I feel that a class is inappropriate anyway.
    I don't think a function will cut it.
    The proposed steps are:
    - Print message to user
    - Grab input using std::getline.
    - Convert std::tstring to T.
    - Validate input.
    - Store input.
    Print message could be a virtual function.
    Grab input is mandatory.
    Convert could be a virtual function, but the conversion itself is mandatory.
    Validate should probably be a function or functor so the user can choose to validate input or not, and how to validate it.
    Store input should be mandatory. It is stored inside the class and the class acts as the input itself.

    At any time later, you could repeat that input without needing to pass messages to user or anything else again. Reusability. Perhaps it should be possible to change the messages printed. What say you to that?

    Convert to T could be specialized for certain types if necessary, but better yet is that boost::lexical_cast will work on any type which has overloaded the proper operators, so the input works with custom classes, as well.

    Quote Originally Posted by citizen View Post
    That didn't seem like part of the specified problem when you first introduced this class in another thread. If part of your goal is simply to remove the tedium in validating and converting built-ins, you can do that easily, and it should greatly assist others in writing the I/O parts of most projects.
    That, and to create even more generic code for reusability. Remove the amount of code the programmer has to type to make it work. That is my goal.
    The idea behind the class was to minimize the code necessary to get input. For example, to get input and validate it, I typically needed these lines of code:
    Code:
    // ... int& Answer
    	// Define variables
    	const std::string Message = "ENGIMA 2005\n"
    								"\n"
    								"Vad vill du g&#246;ra?\n"
    								"(1) Skapa ett krypterat meddelande.\n"
    								"(2) Dekryptera ett meddelande.\n"
    								"(3) Avsluta.\n"
    								"Angel val: ";
    	Stuff::CInput<> input;
    
    	for (;;)
    	{
    		if	( // Validate input
    				((input << Message) >> Answer) &&
    				(Answer >= 1 && Answer <= 3)
    			)
    			break;
    		std::cout << "\nOgtiligt val.\n\n"; // Invalid input
    	}
    Now, if I had to type this on many occasions, I felt it was too much, too much general code that I had to re-type over and over. So why not provide a generic way to solve this? That is when I started to think that maybe I could embed the validation part in the class, because it is partly validating the input already, when converting from std::tstring to T.

    As such, perhaps something better would be:
    Code:
    	// Define variables
    	Stuff::CInput<int> input("ENGIMA 2005\n"
    "\n"
    "Vad vill du g&#246;ra?\n"
    "(1) Skapa ett krypterat meddelande.\n"
    "(2) Dekryptera ett meddelande.\n"
    "(3) Avsluta.\n"
    "Angel val: ", "\nOgtiligt val.\n\n", MinMax(1, 3));
    input.ask();
    Or something along the lines.
    One message to ask the user for input.
    One message or function for error-handling.
    And one function for validation.
    If the user inputs something that is invalid, the class will loop until the input is validated OK.

    This will eliminate the need for a separate variable for each answer, aside from the inputter and gives a greater feel for the class - that it is supposed to be an object. This is not Java, so everything that is not an object does not have to be a class.
    And I also believe I was given the understanding that using as a generic inputter or binding it to one input (ie the object itself) did not matter that much, as long as the implementation was correct, naturally.

    IMO, it is just as important that some of the methods in your class don't validate, or it could be a reason to keep the validation method protected by the class. Presumably, you would just specialize the template for built-ins before you ship the library. Their validation algorithms could be coded in terms of stringstreams and the manipulators in <iomanip>, for example, if you are feeling especially lazy. Users of your class could then build operator>> for their class in terms of these. Now they can optionally use whatever "grab it" function you provide in your interface without much cause for concern. Is that an acceptable use of your class?
    The idea is to keep the class customizable so that programmers can override the behavior to their needs. The validation part should be optional, so it is not enforced if not necessary. It should not be necessary to circumvent the implementation...

    But I believe that lambda expressions are functors, though? So using a "function" approach, would it be able to accept lambda expressions in C++0x?
    If your thoughts are against this, then I would like to hear why and alternatives.
    (Oh and btw, this is or was code for a test for a course.)
    Last edited by Elysia; 11-12-2008 at 06:13 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.

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

    Yea... too much to respond to in my usual fashion. I'll just offer some ideas (disguised as questions*):

    Why are you using 'std::getline' by default?
    Why make one class responsible for so much work?
    Why use a simple string as an argument related to prompting a user for input?
    Why use a simple string as an argument related to providing an error message?
    Why does the error message appear unrelated to the validation function?
    Why not decouple this "dumb user handler" class mechanic from types and constructs not necessarily related to input and output?
    Have you studied many of the applications of expression templates?

    Soma

    * I've taken to notifying people of rhetoric. It saves time later.

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> I don't think a function will cut it. <<
    Why? I don't see a class when I look at your proposed steps, I see a procedure. For reasons forthcoming, you haven't quite given a rationale for the design of this class and the example as I read it fulfills all of the requirements you've listed.

    Often the extraction operator does all three of these:
    - Convert std::tstring to T.
    - Validate input.
    - Store input.

    In particular, if the conversion from string to T is valid then the input is valid. Granted this is not necessarily the case for all extractors, but a number of them. Why doesn't that fit into your rationale?

    >> This will eliminate the need for a separate variable for each answer, aside from the inputter and gives a greater feel for the class <<
    I wanted to respond to this first. Why is that a good thing? C++ programmers are quite comfortable with the concept of streams and extracting individual datum from them. Any reason for going against the grain?

    >> Now, if I had to type this on many occasions, I felt it was too much, too much general code that I had to re-type over and over. So why not provide a generic way to solve this? <<
    Because not all I/O operations are interactive? Because input and output are fundamental parts of the problem-solving process and there are a diverse number of problems? I agree that you can abstract away a lot of the repetitive solutions, (see the proposed procedure as an example - if you ever agree they in fact "cut it" at some point) which is why I don't outright bash the attempt. I just never agreed with the design, and you asked for my opinion. Perhaps it's my inexperience talking but I have to resolve I/O program by program at this point because they're all somewhat different. I feel like I'm changing horses midstream and I apologize to readers who might be confused.

    I feel as though you are trying to design an all-encompassing solution to interactive input, but at the moment I do not see how this saves me any work apart from the fact that I would not need to use control structures if I used an inputter instead. Let me tell you that the solution with control structures is easier to document, debug, and maintain--especially for other C++ programmers. You probably agree, since if I wanted to extend this class for any complicated data type then I need to abstract away validation methods and shove them in your class somehow ...

    >> This is not Java, so everything that is not an object does not have to be a class. <<
    To wit, everything which is an object is an instantiation of a class by definition.


    With all the problems class design seems to have in regards to the problem I cannot agree that it is the best route to take. Part of what makes C++ nice is that you can solve it naturally.
    Last edited by whiteflags; 11-12-2008 at 07:25 AM.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    At any time later, you could repeat that input without needing to pass messages to user or anything else again. Reusability. Perhaps it should be possible to change the messages printed. What say you to that?
    All I can say is, "Huh?"

    You lost me at
    I don't think a function will cut it.
    As citizen said, why? No, let me rephrase that. Why?

    What do you mean by "repeat that input"? Why would you want to repeat the input?

    When I do user input, I care about three things:
    1) I want to prompt the user.
    2) I want to read a value.
    3) I want to validate it, and if necessary, emit an error and start over.
    In particular, I want the value to end up in a normal variable of the value type, not hidden inside an input object. The moment I have validated the value, I no longer care that it was user input.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There is so much to respond to. How I love these little design chats
    They give such a lot of feedback. I will not incorporate any more changes until I've decided at a proper design, by listening to feedback and incorporating it into my design.

    Quote Originally Posted by phantomotap View Post
    Why are you using 'std::getline' by default?
    Because of the usual approach - read a string, convert it to appropriate type. If it fails, there is no need to clear the stream or other complications. It's my preferred method of doing inputs.

    Why make one class responsible for so much work?
    I don't know. I don't see how I would place it all inside different classes and still maintain the easy solution of use for a (single) object.
    Although you do give me the sense that there can be several versions of the input class, each tailored to a somewhat different approach.

    Why use a simple string as an argument related to prompting a user for input?
    The prompt could be of any type, so long as it can be outputted by an appropriate stream. That, too, could be changed, though, if one provided custom traits.

    Why use a simple string as an argument related to providing an error message?
    For error, a function or functor or an error message could be passed, depending on the design. That is my planning.

    Why does the error message appear unrelated to the validation function?
    The code is not perfect here, either, of course.
    Either it should output an error and do the input process over or it should call a functor or function that handles the error process and probably starting the process over again.

    Why not decouple this "dumb user handler" class mechanic from types and constructs not necessarily related to input and output?
    You want to put the conversion and validation process as part of separate class(es)? IS that what you mean or did you have something else in mind?

    Have you studied many of the applications of expression templates?
    I don't know what expression templates are, so no, unfortunately...

    Quote Originally Posted by citizen View Post
    >> I don't think a function will cut it. <<
    Why? I don't see a class when I look at your proposed steps, I see a procedure. For reasons forthcoming, you haven't quite given a rationale for the design of this class and the example as I read it fulfills all of the requirements you've listed.
    Quote Originally Posted by CornedBee View Post
    All I can say is, "Huh?"

    You lost me at

    As citizen said, why? No, let me rephrase that. Why?

    What do you mean by "repeat that input"? Why would you want to repeat the input?

    When I do user input, I care about three things:
    1) I want to prompt the user.
    2) I want to read a value.
    3) I want to validate it, and if necessary, emit an error and start over.
    In particular, I want the value to end up in a normal variable of the value type, not hidden inside an input object. The moment I have validated the value, I no longer care that it was user input.
    What I meant is as in your example. You read the input. Then you begin to validate it. You find out that it doesn't cut the requirements, so you ask again.
    So instead of typing ask(msg, error, ...) all the time, you could bind those things at the time of creation. Then all you would have to do is call ask().
    I don't know if it has many advantages, it just seems natural to me that an object should be able to do that. In sense that it may be a someone whom you task for getting input: say this, and the answer you get must conform to these requirements. And then later you can say: ask again.

    Often the extraction operator does all three of these:
    - Convert std::tstring to T.
    - Validate input.
    - Store input.

    In particular, if the conversion from string to T is valid then the input is valid. Granted this is not necessarily the case for all extractors, but a number of them. Why doesn't that fit into your rationale?
    Generally, it does, but what if I want the answer to be no less than 1 or greater than 3? I have to check manually, but I want to be able to pass this off to the input validation, if possible.
    Perhaps you may have some other exotic requirements, as well, mostly with custom classes. I think this applies mostly to built-in types, I suppose.

    >> This will eliminate the need for a separate variable for each answer, aside from the inputter and gives a greater feel for the class <<
    I wanted to respond to this first. Why is that a good thing? C++ programmers are quite comfortable with the concept of streams and extracting individual datum from them. Any reason for going against the grain?
    I don't know. It seemed more natural to make the class the actual answer itself.
    I can do either way, though.

    >> Now, if I had to type this on many occasions, I felt it was too much, too much general code that I had to re-type over and over. So why not provide a generic way to solve this? <<
    Because not all I/O operations are interactive? Because input and output are fundamental parts of the problem-solving process and there are a diverse number of problems? I agree that you can abstract away a lot of the repetitive solutions, (see the proposed procedure as an example - if you ever agree they in fact "cut it" at some point) which is why I don't outright bash the attempt. I just never agreed with the design, and you asked for my opinion. Perhaps it's my inexperience talking but I have to resolve I/O program by program at this point because they're all somewhat different. I feel like I'm changing horses midstream and I apologize to readers who might be confused.
    I realize that all uses may not be the same, and as such, you need great control over what happens. The original idea was to remove repeating code, by placing the work inside a class and building a flexible but easy interface.
    That is the very reason I want to provide more control over how it works, to customize certain steps of the way without the need to specialize a lot of template classes for many types, and preferably also not having to derive the class, though that could be a solution, too.

    I want to create a piece of code that can easily incorporate and simplify the input process, so you don't have to repeat code all over the place. With specialized functors and stuff, it could be a simple way of customizing the class for different uses over many projects. That's how I feel.

    I feel as though you are trying to design an all-encompassing solution to interactive input, but at the moment I do not see how this saves me any work apart from the fact that I would not need to use control structures if I used an inputter instead. Let me tell you that the solution with control structures is easier to document, debug, and maintain--especially for other C++ programmers.
    I do feel the same, and I believe it will have advantages, if only for myself.
    As to the maintain and understanding part... If you provide functors that validate your inputer, pretty much all you would not need is a loop. Less typing, less lines. And I feel it is no different from using an algorithm to perform tasks (such as std::for_each instead of a for loop).
    Of course, some may like this, and some may not. That is why I also want to give control to the programmer to use it as they see naturally. I don't know if this is a bad idea.

    The idea is that you can or can not have the validation inside the class. All it can do for you, if you want, is get the input, convert and store it. You can then retrieve it and validate it on your own.

    You probably agree, since if I wanted to extend this class for any complicated data type then I need to abstract away validation methods and shove them in your class somehow ...
    Well, I found it easier to use a more abstract way instead of a way after retrieving the input. But you might just as well just a big number of If statements, if you wish.

    >> This is not Java, so everything that is not an object does not have to be a class. <<
    To wit, everything which is an object is an instantiation of a class by definition.
    With all the problems class design seems to have in regards to the problem I cannot agree that it is the best route to take. Part of what makes C++ nice is that you can solve it naturally.
    The function actually gave me something to think about, but the more I do think about it, the more I seem to think it does not cut the problem, from my view. Especially not if I go on to make it work in a different number of ways. Flexibility is always the key in C++!
    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.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    In sense that it may be a someone whom you task for getting input: say this, and the answer you get must conform to these requirements. And then later you can say: ask again.
    Code:
    auto betweenOneAndThree = [](int i) -> bool { return i >= 1 && i <= 3; };
    auto getValueBetweenOneAndThree =
        std::bind(&getInput<int>, _1, betweenOneAndThree,
                 "Your input isn't an integer between one and three.");
    
    int i1 = getValueBetweenOneAndThree();
    int i2 = getValueBetweenOneAndThree();
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Inheritance is really the only way to do this generally.

    Code:
    template <typename InType, typename OutType>
    class generic_functor
    {
    public:
        virtual ~generic_functor() {}
    
        virtual OutType operator()(const InType &val) = 0;
    };
    
    template <typename InType, typename OutType, typename Func>
    class concrete_functor : public generic_functor<InType, OutType>
    {
    public:
        concrete_functor(Func func)
          : function(func)
        {}
    
        OutType operator()(const InType &val)
        {
            return function(val);
        }
    
    private:
        Func function;
    };
    Now you store a pointer to a generic_functor<I, O> which points to some concrete_functor. You would use a templatized constructor to initialize it:

    Code:
    template <typename InType, typename OutType>
    class some_container
    {
    public:
        template <typename Func>
        some_container(..., Func func)
          : functor(new concrete_functor<InType, OutType, Func>(func))
        {}
    
        ~some_container()
        {
            delete functor;
        }
    
    private:
        generic_functor<InType, OutType> *functor;
    };
    You might avoid needing the destructor in some_container by using some kind of smart pointer to point at the generic_functor
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    Code:
    auto betweenOneAndThree = [](int i) -> bool { return i >= 1 && i <= 3; };
    auto getValueBetweenOneAndThree =
        std::bind(&getInput<int>, _1, betweenOneAndThree,
                 "Your input isn't an integer between one and three.");
    
    int i1 = getValueBetweenOneAndThree();
    int i2 = getValueBetweenOneAndThree();
    That is another way of doing it, I suppose, so... what I'm guessing you are trying to say is that it is only a waste of time to implement such functionality within the class itself (even though it may seem natural)?
    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. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Yes, pretty much.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    So, I am to understand the following changes:
    - Pre-input events (such as printing a message) should probably be done by the programmer.
    - The class should be generic - it should not store any permanent value.
    - The class may or may not validate the input (other than converting to the appropriate type) - that decision is left up to the programmer. There may be pre-defined functors for validation.

    So I am thinking:
    Code:
    CInput<T> myinputter( MinMax(1, 3) );
    T input;
    do
    {
        std::cout << "My message";
    }
    while (!myinputter >> input)
    If the input fails, the input object is left in a "bad" state and thus the loop starts over.

    Perhaps there is the possibility for a "helper" class that basically takes a message to print, an error-message or error function and performs this loop for you?
    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. Storing Cstrings in an Array
    By Tien1868 in forum C Programming
    Replies: 4
    Last Post: 07-09-2009, 07:48 PM
  2. Storing Passwords/Encryption
    By Tonto in forum C++ Programming
    Replies: 8
    Last Post: 07-01-2009, 09:05 PM
  3. Storing Objects in txt files?
    By Swerve in forum C++ Programming
    Replies: 4
    Last Post: 03-15-2009, 12:17 PM
  4. Variable Storing in memory
    By karb0noxyde in forum C++ Programming
    Replies: 7
    Last Post: 10-11-2004, 07:31 PM
  5. File Reading and storing to 1 variable
    By Rare177 in forum C Programming
    Replies: 34
    Last Post: 07-13-2004, 12:58 PM