* Kai-Uwe Bux:
As for the name: it actually prompts.
Well, but it does more than that, doesn't it?
As I see it that prompt business is a secondary thing.
Anyway, I meant to get rid of the goto without introducing a flag variable.
Note what the flag is used for: to remember the goodness of the stream until
after the stream has been cleared and line emptied.
Which IMHO should be done regardless of success or failure this iteration.
If the flag variable is removed and replaced by a position in the code, then
without using RAII I think there will necessarily be code duplication: the
cleanup actions duplicated for the cases of success and failure for this
iteration.
The simplest RAII would be to use a ScopeGuard object, but that brings in the
whole ScopeGuard header, which is too much to present here.
A Do-It-Yourself RAII-based version might go like this:
class StreamCleanup
{
private:
std::istream& myStream;
StreamCleanup& operator=( StreamCleanup const& ); // None.
public:
StreamCleanup( std::istream& s ): myStream( s ) {}
~StreamCleanup()
{
myStream.clear();
myStream.ignore( std::numeric_limits<int>::max(), '\n' );
}
};
template< typename T >
T numberFromUser( T min, T max )
{
for( ;; )
{
StreamCleanup cleaner( std::cin );
T n;
std::cout
<< "Enter a number from " << min << " to " << max << ": ";
std::cin >> n; // cin and cout are synchronized.
if( std::cin.good() && min <= n && n <= max )
{
return n;
}
}
}
Cheers,
- Alf