C++ 创建临时对象来调用成员函数

标签 c++ c++11

下面代码中出现编译错误的代码行(在注释中)有什么问题?我认为应该使用 const std::string 调用 TestMe 构造函数,然后对其调用operator()。但看起来它正在尝试使用变量 a 构造 TestMe

#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;
}

编译错误:

../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");

最佳答案

“最令人烦恼的解析”:https://www.fluentcpp.com/2018/01/30/most-vexing-parse/

TestMe( a )() 被视为名为 a 的函数的声明,该函数不带参数并返回 TestMe 对象.

稍微更改您的程序,以便相关行不会与名称 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;
}

您将看到 TestMe( b )(); 行不会产生任何输出,因为它只是一个声明:

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

关于C++ 创建临时对象来调用成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67498516/

相关文章:

c++ - b2 的命令参数,以便使用 Microsoft 的 Clang/C2 构建 Boost 库

c++ - 初始化程序列表在 Visual Studio 2012 Update 2 CTP 4(3 月)中不起作用

c++11 - LLVM IR Lambda 函数

c++ - Qt3D骨骼动画

通过引用传递的 C++0x 初始化列表

c++ - MSVC++ 6.0 devshl.dll 错误

c++ - 从 C++ 打印共享库依赖项

c++ - 函数是否可能只接受给定参数的一组有​​限类型?

c++ - 如何在 Visual Studio C++ 中的 Intellisense 自动完成方法名称后自动插入括号

c++ - 在编译时构建类型列表 - 无 C++11