単純な RAII ラッパーを作成しているときに、予期しない問題に遭遇しました。
以下のコードの論理的な不完全さ (コピー コンストラクターと代入演算子が削除されていないなど、これは SSCCE を意味する) は言うまでもなく、一時的なラムダを使用してラッパーをコピー初期化するとコンパイル エラーが発生することに驚かされます。 、直接初期化はしません。
この動作は GCC 4.7.2 と Clang 3.2 の両方で確認できますが、ICC 13.0.1 と VC10 は両方のバージョンを問題なくコンパイルします。
#include <iostream>
#include <functional>
using namespace std;
struct A
{
template<typename F>
A(F&& f) : _f(forward<F>(f)) { }
~A() { _f(); }
private:
std::function<void()> _f;
};
int main()
{
// A a = [] () { cout << "Hello" << endl; }; // ERROR!
A a([] () { cout << "Hello" << endl; }); // OK
}
誰が正しくて、間違っている人には何が問題なのですか? C++ 標準ライブラリの実装の問題ですか、それともコンパイラの問題ですか?
C++11 標準への参照は特に歓迎されます。
編集:
Clang 3.2 で生成されるエラーは次のとおりです。
Compilation finished with errors:
In file included from source.cpp:2:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/functional:1925:2: error: type 'A' does not provide a call operator
(*_Base::_M_get_pointer(__functor))(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/functional:2297:33: note: in instantiation of member function 'std::_Function_handler<void (), A>::_M_invoke' requested here
_M_invoker = &_My_handler::_M_invoke;
^
source.cpp:9:16: note: in instantiation of function template specialization 'std::function<void ()>::function<A>' requested here
A(F&& f) : _f(forward<F>(f)) { }
^
source.cpp:20:7: note: in instantiation of function template specialization 'A::A<A>' requested here
A a = [] () { cout << "Hello" << endl; }; // ERROR!
^
1 エラーが発生しました。