lundi 26 septembre 2022

Passing a temporary stream object to a lambda function as part of an extraction expression

I have a function which needs to parse some arguments and several if clauses inside it need to perform similar actions. In order to reduce typing and help keep the code readable, I thought I'd use a lambda to encapsulate the recurring actions, but I'm having trouble finding sufficient info to determine whether I'm mistakenly invoking undefined behavior or what I need to do to actualize my approach.

Below is a simplified code snippet of what I have currently:

int foo(int argc, char* argv[])
{
    Using ss = std::istringstream;

    auto sf = [&](ss&& stream) -> ss& {
        stream.exceptions(ss::failbit);
        return stream;
    };

    int retVal = 0;

    bool valA = false;
    bool valB = false;

    try
    {
        for(int i=1; i < argc; i++)
        {
            std::string arg( argv[i] );

            if( !valA )
            {
                valA = true;
                sf( ss(arg) ) >> myInt;
            }
            else
            if( !valB )
            {
                valB = true;
                sf( ss(arg) ) >> std::hex >> myOtherInt;
            }
        }
    }
    catch( std::exception& )
    {
        retVal = -1;
        std::cerr << err.what() << std::endl;
    }
    
    return retVal;
}

First, based on what I've read, I don't think that specifying the lambda argument as an rvalue reference (ss&&) is doing quite what I want it to do, however, trying to compile with it declared as a normal reference (ss&) failed with the error cannot bind non-const lvalue reference of type 'ss&'. Changing ss& to ss&& got rid of the error and did not produce any warnings, but I'm not convinced that I'm using that construct correctly.

I've tried reading up on the various definitions for each, but the wording is a bit confusing.

I guees my ultimate questions are:

  1. Can I expect the lifetime of my temporary ss(arg) object to extend through the entire extraction expression?

  2. What is the correct way to define a lambda such that I can use the lambda in the way I demonstrate above, assuming that such a thing is actually possible?

Aucun commentaire:

Enregistrer un commentaire