Ошибка компиляции: параметры функции, использующие ссылки на объекты, сбиваются с толку созданными объектами - PullRequest
0 голосов
/ 11 февраля 2010

В модульном тесте класса я пытаюсь объявить переменную класса, явно вызвав пустой конструктор и передав его в функцию, которая исключает ссылку на интерфейс типа, который я объявляю, но компилятор выдает ошибку,Когда я просто объявляю это без какого-либо явного вызова конструктора, функция принимает его.

См. Код ниже:

//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);
}

Компилятор считает, что controllerB является ссылкой конструктора:

ошибка: нет соответствующей функции для вызова `CClassUnderTest :: Run (CTestController (&) ()) 'ошибка: кандидаты: unsigned int CClassUnderTest :: Run (IController &)

Меня смущает, почему компилятор не позволяет мне вызывать конструктор при создании экземпляра controllerB, особенно, когда рабочий код выглядит нормально с этим?

1 Ответ

6 голосов
/ 11 февраля 2010

Эта строка:

CTestController controllerB();

- это объявление функции, которая ничего не берет и возвращает CTestController. Для построения по умолчанию вы должны просто оставить скобки.

Это связано с тем, что называется "самый неприятный анализ". Рассмотрим:

struct S {};

int main()
{
    S s(S()); // copy construct a default-constructed S ...?
}

Это не работает. Это объявляет s как функцию, которая берет указатель на функцию, которая ничего не берет и возвращает S, которая возвращает S. Чтобы исправить это, вы можете использовать дополнительный набор скобок:

struct S {};

int main()
{
    S s((S())); // copy construct a default-constructed S :)
}
...