私は、コンテナを反復処理し、各要素をフィルタリングのための述語に渡す関数を持っています。この関数のオーバーロードは、各要素のインデックスも述語に渡します。C++ラムダは正しくオーバーロードされた関数を選択しませんか?
template<typename TContainer>
void DoSomethingIf(TContainer &c, std::function<bool (const typename TContainer::const_reference)> predicate);
template<typename TContainer>
void DoSomethingIf(TContainer &c, std::function<bool (const typename TContainer::const_reference, int)> predicate);
私は成功するのstd ::関数オブジェクトを使用しながら、裸のラムダで、これらの機能のいずれかを呼び出そうとすると、VC11でコンパイルエラーが発生しますことを発見した:
void foo()
{
std::vector<int> v;
// fails
DoSomethingIf(v, [](const int &x) { return x == 0; });
// also fails
auto lambda = [](const int &x) { return x == 0; };
DoSomethingIf(v, lambda);
// success!
std::function<bool (const int &)> fn = [](const int &x) { return x == 0; };
DoSomethingIf(v, fn);
}
1>c:\users\moswald\test.cpp(15): error C2668: 'DoSomethingIf' : ambiguous call to overloaded function
1> c:\users\moswald\test.cpp(8): could be 'void DoSomethingIf<std::vector<_Ty>>(TContainer &,std::function<_Fty>)'
1> with
1> [
1> _Ty=int,
1> TContainer=std::vector<int>,
1> _Fty=bool (const int &,int)
1> ]
1> c:\users\moswald\test.cpp(5): or 'void DoSomethingIf<std::vector<_Ty>>(TContainer &,std::function<_Fty>)'
1> with
1> [
1> _Ty=int,
1> TContainer=std::vector<int>,
1> _Fty=bool (const int &)
1> ]
1> while trying to match the argument list '(std::vector<_Ty>, foo::<lambda_8EADDE04A8D35A3C>)'
1> with
1> [
1> _Ty=int
1> ]
1>c:\users\moswald\test.cpp(19): error C2668: 'DoSomethingIf' : ambiguous call to overloaded function
1> c:\users\moswald\test.cpp(8): could be 'void DoSomethingIf<std::vector<_Ty>>(TContainer &,std::function<_Fty>)'
1> with
1> [
1> _Ty=int,
1> TContainer=std::vector<int>,
1> _Fty=bool (const int &,int)
1> ]
1> c:\users\moswald\test.cpp(5): or 'void DoSomethingIf<std::vector<_Ty>>(TContainer &,std::function<_Fty>)'
1> with
1> [
1> _Ty=int,
1> TContainer=std::vector<int>,
1> _Fty=bool (const int &)
1> ]
1> while trying to match the argument list '(std::vector<_Ty>, foo::<lambda_8EADDE04A8D35A3D>)'
1> with
1> [
1> _Ty=int
1> ]
これは期待されていますか?これらの関数をオーバーロードする別の方法は、過負荷の曖昧さが期待されている?「DoSomethingIfWithIndex
」に1をリネームの短い(
は感覚が、期待はずれにします。これは、異なるラムダを通して過負荷関数を選択する方法が決してないことを意味するように見えます。 – moswald
'std :: function'を使用していません。呼び出し可能な特性を使用したり、キャプチャのないラムダの関数ポインタの減衰に頼ることはできますが、一般的にはバットの痛みです。 –
このような問題を解決するために、呼び出し可能な特性を使用するにはどうすればよいでしょうか?可能であれば、自由な関数/ lambdaだけでなく、署名に合った関数オブジェクトを渡すことができるようにしたいと思います。 – moswald