invalid use of auto in expression ??

Discussion in 'C++' started by mdcb808@gmail.com, May 8, 2012.

  1. Guest

    Hello all,

    I was wondering if this was legit C++11x

    std::map<std::string, int> m;
    ...

    (1) if ((auto bar = m.find("bar")) == m.end()) std::cout << "bar not found\n";

    breaking it down in 2 steps keeps my compiler happy:

    (2) auto foo = m.find("foo");
    if (foo == m.end()) std::cout << "foo not found\n";


    Is this guided by the standard, or a limitation with my compiler?

    Thanks
     
    , May 8, 2012
    #1
    1. Advertising

  2. On 08.05.2012 20:33, wrote:
    >
    > Hello all,
    >
    > I was wondering if this was legit C++11x
    >
    > std::map<std::string, int> m;
    > ...
    >
    > (1) if ((auto bar = m.find("bar")) == m.end()) std::cout<< "bar not found\n";
    >
    > breaking it down in 2 steps keeps my compiler happy:
    >
    > (2) auto foo = m.find("foo");
    > if (foo == m.end()) std::cout<< "foo not found\n";
    >
    >
    > Is this guided by the standard, or a limitation with my compiler?


    It has nothing to do with `auto`.

    The above is analogous to

    (int x = foo()) == 666

    In general you can't put declarations within expressions. The support
    for a declaration in a /condition/ is very rudimentary, and the
    initializer is just converted to bool for the decision. Mostly it's only
    useful for a `dynamic_cast` as initializer.

    You're not using the name you attempt to declare, so it's difficult to
    say how to express what you're attempting (but fail to show).

    Maybe post separately about that.


    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, May 8, 2012
    #2
    1. Advertising

  3. On May 8, 11:33 am, wrote:
    > Hello all,
    >
    > I was wondering if this was legit C++11x
    >
    >   std::map<std::string, int> m;
    >   ...
    >
    > (1)  if ((auto bar = m.find("bar")) == m.end()) std::cout << "barnot found\n";
    >
    > breaking it down in 2 steps keeps my compiler happy:
    >
    > (2)  auto foo = m.find("foo");
    >      if (foo == m.end()) std::cout << "foo not found\n";
    >
    > Is this guided by the standard, or a limitation with my compiler?
    >
    > Thanks


    I don't have a chapter and verse to cite, but I don't think the above
    form (1) is allowed in either C++ 03 or 11 (neither with "auto" nor
    with an actual explicit type). This won't compile either:

    if ((int foo = getSomeInt()) == 5) { doSomething(foo); }


    Perhaps you're thinking of this form, which is slightly less
    featureful but does compile:

    if (int foo = getSomeInt()) { doSomething(foo); }

    This calls doSomething(foo) if a boolean conversion of the value
    assigned to foo from getSomeInt() is true. It's a nice replacement
    for

    int foo = getSomeInt();
    if (foo) { doSomething(foo); }

    which keeps the scope of foo better-contained.


    So I'd imagine that the following should work in C++ 11 (not tested)

    if (auto foo = getSomething()) { doSomething(foo); }


    This doesn't help with your particular example, though. On the other
    hand, your example isn't using the value of 'bar' anyway, so you could
    simply use

    if (m.find("bar") == m.end()) std::cout << "bar not found\n";

    - Kevin B. McCarty
     
    Kevin McCarty, May 8, 2012
    #3
  4. Guest

    Thanks you both answered my question, although I had to convince myself compiling Kevin's simple case so I was not day dreaming.
    I guess what I had in mind was along:

    map<string, MyObject *> mymap;

    if ( (auto obj = mymap.find(key) ) == mymap.end() ) {
    // deal with it
    } else {
    obj.do_work()
    }

    Cheers
     
    , May 9, 2012
    #4
  5. On 5/8/2012 7:12 PM, wrote:
    > Thanks you both answered my question, although I had to convince myself compiling Kevin's simple case so I was not day dreaming.
    > I guess what I had in mind was along:
    >
    > map<string, MyObject *> mymap;
    >
    > if ( (auto obj = mymap.find(key) ) == mymap.end() ) {
    > // deal with it
    > } else {
    > obj.do_work()
    > }


    I rarely use that form, and I don't remember whether 'obj' is still
    declared in the 'else' block or not, so I would actually write (if it
    were possible):

    if ((auto obj = mymap.find(key) != mymap.end())
    {
    obj.do_work();
    }
    else
    {
    // deal with it
    }

    The more common idiom *I* use involves a pointer:

    if (SomeType* pBlah = getThePointerSomehow())
    {
    // use the non-null pBlah
    }
    else
    {
    // even if 'pBlah' is still declared here, it's null,
    // so no reason to involve that name
    }

    which should explain why I don't care to learn whether 'pBlah' would be
    still declared in the 'else' part :)

    Now, with your 'find/end' stuff, the only way I see to combine the
    declaration/definition/initialization is to declare your own wrapper for
    the "find" operation:

    template<class C> struct find_wrapper {
    C& co;
    typename C::iterator it;
    template<class W> find_wrapper(C& c, const W& w)
    : co(c), it(c.find(w)) {}
    // here is the key thing that allows declaring it in an 'if'
    operator bool() const { return it != co.end(); }
    typename C::iterator::value_type& obj() { return *it; }

    void operator =(const find_wrapper&) {}
    };

    template<class C, class W>
    find_wrapper<C> do_find(C& co, const W& w) {
    return find_wrapper<C>(co, w);
    }

    #include <map>

    int main()
    {
    std::map<int,double> mymap;
    int key = 666;

    mymap.find(key);

    if (auto finder = do_find(mymap, key))
    {
    // use finder.obj() somehow:
    std::pair<int,double> id = finder.obj();
    }
    else
    {
    // deal with it
    }
    }

    Feel free to modify it.

    Victor
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, May 10, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?V2FyYW4=?=

    Auto-Suggested Textbox like google auto suggest

    =?Utf-8?B?V2FyYW4=?=, Apr 20, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    8,538
    inrakeshworld
    Jul 27, 2007
  2. Patrick.O.Ige
    Replies:
    1
    Views:
    1,983
    Patrick.O.Ige
    Jul 2, 2006
  3. Java Guy
    Replies:
    1
    Views:
    697
    Manish Pandit
    Oct 15, 2006
  4. linkswanted
    Replies:
    1
    Views:
    949
  5. Fred Nurk

    error: invalid use of void expression

    Fred Nurk, Jun 27, 2010, in forum: C Programming
    Replies:
    15
    Views:
    2,311
    Vincenzo Mercuri
    Jun 29, 2010
Loading...

Share This Page