6

以下はコンパイルされません。

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)と文句を言います。デフォルトのコンストラクターを追加すると、それが機能し、実際に呼び出されます。このステートメントにデフォルトのコンストラクターが必要なのはなぜですか?

4

1 に答える 1

13

これ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’
于 2010-03-03T14:33:10.357 に答える