views:

38

answers:

1

In the unit test of a class, I try to declare a class variable by calling explicitly the empty constructor and pass it to a function that excepts a reference to the interface of the type I'm declaring, but the compiler produces error. When I just declare it without any explicit constructor call the function accepts it.

See the code below:

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

The compiler believes controllerB is the reference of the constructor:

error: no matching function for call to `CClassUnderTest::Run(CTestController (&)())' error: candidates are: unsigned int CClassUnderTest::Run(IController&)

I'm confused by why the compiler won't allow me to call the constructor when instantiating controllerB, especially when the production code seems okay with this?

+6  A: 

This line:

CTestController controllerB();

is the declaration of a function that takes nothing and returns a CTestController. For default construction, you must simply leave off the parenthesis.

This is related to something called the "most vexing parse". Consider:

struct S {};

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

This doesn't work. This declares s as a function that takes a pointer to a function that takes nothing and returns an S, that returns an S. To fix this, you can use an extra set of parenthesis:

struct S {};

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