Следующее не компилирует:
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
Реализация Панели не имеет значения. Компилятор жалуется, что у Foo нет соответствующего конструктора по умолчанию (VC ++ 2005). Если я добавляю конструктора по умолчанию, он работает, и это на самом деле называют. Почему этот оператор требует конструктора по умолчанию?
Это происходит потому, что BOOST_CHECK_THROW
является макросом, а Foo (bar)
расширяется до оператора. Компилятор видит этот оператор и интерпретирует его как объявление переменной Foo bar;
, для которого требуется конструктор по умолчанию.
Решение состоит в том, чтобы присвоить переменной имя:
BOOST_CHECK_THROW( Foo temp( bar ), std::logic_error );
Другими словами BOOST_CHECK_THROW
будет расширяться до чего-то вроде
try
{
Foo(bar);
// ... fail test ...
}
catch( std::logic_error )
{
// ... pass test ...
}
, а компилятор интерпретирует Foo (bar);
как объявление переменной с именем bar. Это можно проверить с помощью простой программы:
struct Test
{
Test(int *x) {}
};
int main()
{
int *x=0;
Test(x);
return 0;
}
, которая дает следующие ошибки с 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’