gpt4 book ai didi

c++ - C++ lambda 不能正确选择重载函数吗?

转载 作者:IT老高 更新时间:2023-10-28 23:15:15 27 4
gpt4 key购买 nike

我有一个函数可以遍历容器并将每个元素传递给谓词进行过滤。此函数的重载还将每个元素的索引传递到谓词中。

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);

我发现尝试使用裸 lambda 调用这些函数中的一个会导致 VC11 中的编译器错误,而使用 std::function 对象会成功:

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”?

最佳答案

预计会出现过载歧义。

std::function 有一个可以接受任何参数的转换构造函数模板。只有在构造函数模板被实例化后,编译器才能确定它会拒绝该参数。

在您的第一个和第二个示例中,都需要用户定义的转换来将未指定的 lambda 类型转换为每个 std::function 类型。两种转换都不是更好(它们都是用户定义的转换),因此编译器会报告重载歧义。

在您的第三个示例(有效的示例)中,没有歧义,因为未使用 std::function 构造函数模板。相反,它使用了它的复制构造函数(并且,在所有其他条件相同的情况下,非模板优先于模板)。

关于c++ - C++ lambda 不能正确选择重载函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9339717/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com