編集:
これは、Microsoft Connect (リンク)で VS2012 C++ コンパイラのバグとして報告されています。
2014 年 11 月 11 日: Microsoft は、このバグの修正が Visual C++ の次のメジャー リリースで表示されるはずであると回答しました。
私は理解できないVS2012コンパイラエラーメッセージに苦労していたので、問題を最小限に抑えました。
私はmain.cpp
VS2012を使用して以下を構築しています:
#include <utility>
template <typename T>
struct A
{
T x;
A(A&& other) : x(std::move(other.x)) { }
A(T&& x) : x(std::move(x)) { }
};
template <typename T>
A<T> build(T&& x)
{
return A<T>(std::move(x));
}
int main(int argc, char* argv[])
{
auto f = []()
{
return build([](){}); //error here
};
return 0;
}
顕著な点は、ラムダを関数のテンプレート型として使用しようとしていることT
ですbuild
。私が得るエラーメッセージは次のとおりです。
1> main.cpp
1>C:\test\main.cpp(21): error C2664: 'A<T>::A(A<T> &&)' : cannot convert parameter 1 from 'A<T>' to 'A<T> &&'
1> with
1> [
1> T=void (__cdecl *)(void)
1> ]
1> and
1> [
1> T=main::<lambda_c3c618d445b3cb24eede9bf304860ad7>::()::<lambda_4240e93016e3e420ff8383c9350ae130>
1> ]
1> and
1> [
1> T=void (__cdecl *)(void)
1> ]
1> Reason: cannot convert from 'A<T>' to 'A<T>'
1> with
1> [
1> T=main::<lambda_c3c618d445b3cb24eede9bf304860ad7>::()::<lambda_4240e93016e3e420ff8383c9350ae130>
1> ]
1> and
1> [
1> T=void (__cdecl *)(void)
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
調査を行い、エラー メッセージ (リンク)のページを調べましたが、まだ問題の原因がわかりません。このコンパイラエラーについて説明していただけますか?
編集
ここで何かが明らかにおかしい。コードを次のmain
ように変更すると:
auto f = []()
{
int* n = new int(0);
auto g = [=](){ return *n; };
*n++;
return build<decltype(g)>(std::move(g));
};
T=int (__cdecl *)(void)
build の呼び出しでそれを示唆するエラー メッセージが表示されます。これはdecltype(g)
、関数ポインタが与えられていることを意味しますか? は?私はポインタを値でキャプチャし、後でそれを変更しています - ファンクタを作成する必要はありません - そして関数ポインタへのキャストを持たないものですか? たぶん私は何かを理解していません。
関連参照:ラムダ式 : n3290 ドラフト
また、これがVS2012 コンパイラのバグである場合、回避策を考えてもらえますか?