编译错误:使用对象引用的函数参数被构造对象混淆

Mas*_*asD 0 c++ compiler-errors reference

在类的单元测试中,我尝试通过显式调用空构造函数来声明一个类变量,并将其传递给一个函数,该函数除了对我声明的类型的接口的引用之外,但编译器会产生错误.当我在没有任何显式构造函数调用的情况下声明它时,函数接受它.

请参阅以下代码:

//classundertest.h
class IController;

class CClassUnderTest
{
public:
    CClassUnderTest() {}
    virtual ~CClassUnderTest() {}

    unsigned int Run(IController & controller);
};

//testclassundertest.h
#include "UnitTest++.h"

#include "classundertest.h"
#include "icontroller.h"

class CTestController : public IController
{
public:
    CTestController() : IController() {}
    virtual ~CTestController() {}

    virtual void Play(unsigned int i) {}
};

struct CClassUnderTestFixture
{
    CClassUnderTest classUnderTest;
};

TEST_FIXTURE(CClassUnderTestFixture, RunTest)
{
    CTestController controllerA;   

    CHECK_EQUAL(classUnderTest.Run(controllerA), 105U);

    CTestController controllerB();   

    CHECK_EQUAL(classUnderTest.Run(controllerB), 105U);
}
Run Code Online (Sandbox Code Playgroud)

编译器认为controllerB是构造函数的引用:

错误:没有匹配函数来调用`CClassUnderTest :: Run(CTestController(&)())'错误:候选者是:unsigned int CClassUnderTest :: Run(IController&)

我很困惑为什么编译器在实例化controllerB时不允许我调用构造函数,特别是当生产代码看起来好吗?

GMa*_*ckG 6

这一行:

CTestController controllerB();
Run Code Online (Sandbox Code Playgroud)

是一个函数的声明,它不需要任何东西并返回一个CTestController.对于默认构造,您必须简单地省略括号.

这与称为"最令人烦恼的解析"的东西有关.考虑:

struct S {};

int main()
{
    S s(S()); // copy construct a default-constructed S ...?
}
Run Code Online (Sandbox Code Playgroud)

这不起作用.这声明s为一个函数,它接受一个不带任何东西的函数的指针,并返回一个S,返回一个S.为了解决这个问题,你可以使用一组额外的括号:

struct S {};

int main()
{
    S s((S())); // copy construct a default-constructed S :)
}
Run Code Online (Sandbox Code Playgroud)