简体   繁体   中英

C++ create temporary object to call member function

What's wrong with the line of code with compile errors (in comment), in the code below? I thought it is supposed to call the TestMe constructor with the const std::string , then call operator() on it. But it looks like it is trying to construct TestMe with variable a .

#include <iostream>

namespace
{
class TestMe
{
public:
    TestMe() {}
    TestMe( const std::string& me ) : me_( me ) {}

    bool operator()() const
    {
        std::cout << "calling operator()" << std::endl;
        return true;
    }

private:
    const std::string me_;
};
}


int main()
{
    const std::string a("a");

    //
    // construct an instance of TestMe and call its operator()
    //

    TestMe()();         // OK
    TestMe( "abc" )();  // OK
    TestMe tm( a );     // OK
    TestMe( a )();      // compile error: what's wrong with this?
    TestMe( { a } )();  // OK

    return 0;
}

Compile error:

../src/main.cpp: In function ‘int main()’:
../src/main.cpp:44:14: error: ‘{anonymous}::TestMe a()’ redeclared as different kind of symbol
  TestMe( a )();   // compile error
              ^
../src/main.cpp:35:20: note: previous declaration ‘const string a’
  const std::string a("a");

"Most vexing parse": https://www.fluentcpp.com/2018/01/30/most-vexing-parse/

TestMe( a )() is being treated as a declaration of a function named a that takes no arguments and returns a TestMe object.

Change your program slightly so that the line in question doesn't conflict with the name a :

#include <iostream>

namespace
{
class TestMe
{
public:
    TestMe() {}
    TestMe( const std::string& me ) : me_( me ) {}

    bool operator()() const
    {
        std::cout << "calling operator()" << std::endl;
        return true;
    }

private:
    const std::string me_;
};
}


int main()
{
    const std::string a("a");

    //
    // construct an instance of TestMe and call its operator()
    //

    TestMe()();         // OK
    TestMe( "abc" )();  // OK
    TestMe tm( a );     // OK
    std::cout << "before most vexing parse\n";
    TestMe( b )();      // compiles, but has no effect
    std::cout << "after most vexing parse\n";
    TestMe( { a } )();  // OK

    return 0;
}

You will see that the line TestMe( b )();produces no output because it's just a declaration:

calling operator()
calling operator()
before most vexing parse
after most vexing parse
calling operator()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM