2010-03-03 2 views
3

Ниже не компилируется:Компилятор жалуется BOOST_CHECK_THROW на конструктор

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 

Реализация Bar не имеет значения. Компилятор жалуется, что Foo не имеет соответствующего конструктора по умолчанию (VC++ 2005). Если я добавлю конструктор по умолчанию, он работает, и он фактически вызван. Почему этот оператор требует конструктора по умолчанию?

ответ

9

Это происходит потому, что 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); как объявление переменной с именем бар. Можно проверить это с простой программой:

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

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

, который дает следующие ошибки с г ++

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’ 
+0

Действительно. Благодарю. –

Смежные вопросы