Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler complains about BOOST_CHECK_THROW on constructor

The following does not compile:

class Foo {
public:
    Foo( boost::shared_ptr< Bar > arg );
};

// in test-case

boost::shared_ptr< Bar > bar;

BOOST_CHECK_THROW( Foo( bar ), std::logic_error ); // compiler error here

The implementation of Bar does not matter. The compiler complains, that Foo does not have an appropriate default constructor (VC++ 2005). If I add a default constructor, it works, and it actually gets called. Why does this statement require a default constructor?

like image 799
Björn Pollex Avatar asked Mar 03 '10 14:03

Björn Pollex


1 Answers

This occurs because BOOST_CHECK_THROW is a macro, and Foo(bar) is being expanded to a statement. The compiler sees this statement and interprets it as a variable declaration Foo bar; which requires a default constructor.

The solution is to give the variable a name:

BOOST_CHECK_THROW( Foo temp( bar ), std::logic_error );

In other words BOOST_CHECK_THROW will expand to something like

try
{
    Foo(bar);
    // ... fail test ...
}
catch( std::logic_error )
{
    // ... pass test ...
}

and the compiler is interpreting Foo(bar); as the declaration of a variable called bar. One can check this with a simple program:

struct Test
{
    Test(int *x) {}
};

int main()
{
    int *x=0;
    Test(x);
    return 0;
}

which gives the following errors with g++

test.cpp: In function ‘int main()’:
test.cpp:10: error: conflicting declaration ‘Test x’
test.cpp:9: error: ‘x’ has a previous declaration as ‘int* x’
like image 185
Adam Bowen Avatar answered Nov 05 '22 17:11

Adam Bowen