user1414883
user1414883

Reputation:

No appropriate default constructor available within googletest EXPECT_NO_THROW

Declaration:

class ClassOne
{
    ClassOne (ClassTwo* classTwo, ClassThree const& classThree);
}

Test:

ClassTwo* classTwo;
ClassThree classThree;
EXPECT_NO_THROW (ClassOne (classTwo, classThree));

This compiles and runs, but now I change it to:

Declaration:

class ClassOne
{
    ClassOne (ClassThree const& classThree);
}

Test:

ClassThree classThree;
EXPECT_NO_THROW (ClassOne (classThree));

This fails with "no appropriate default constructor available".

The following lines compile:

ClassOne classOne (classTwo, classThree);    // First case
ClassOne classOne (classThree);    // Second case

Is there some reason why I can't EXPECT_NO_THROW on a constructor with one parameter?

Upvotes: 4

Views: 1360

Answers (2)

Bulletmagnet
Bulletmagnet

Reputation: 6032

You have been bitten by C++'s most vexing parse. The "statement" argument to the EXPECT_NO_THROW macro, ClassOne (classThree), is not a definition of nameless ClassOne object whose constructor gets a ClassThree object named classThree. It is the declaration of a default-constructed ClassOne object, named classThree. It's the same as if you had written EXPECT_NO_THROW (ClassOne classThree); - the parens are optional.

See https://youtu.be/lkgszkPnV8g?t=1750

The solution (if you can use C++11) is to use uniform initialization:

EXPECT_NO_THROW (ClassOne {classThree});

Upvotes: 0

Fraser
Fraser

Reputation: 78388

This is a bug in gtest I think (although I'm no expert on macros). EXPECT_NO_THROW ultimately expands to:

#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
  if (::testing::internal::AlwaysTrue()) { statement; }

Your code compiles using VS2012RC if statement is wrapped in parentheses in the if body:

#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
  if (::testing::internal::AlwaysTrue()) { (statement); }
//                                         ^         ^

As a workaround, you can do:

EXPECT_NO_THROW ((ClassOne (classThree)));

Upvotes: 4

Related Questions