std::find是否隐式修复无效参数

Does std::find implicitly fix invalid arguments?

本文关键字:无效 参数 find 是否 std      更新时间:2023-10-16

所以我有一个非常奇怪的情况,我的一个程序正在工作,而据我所知,它不可能工作。因此,这个问题只是因为我想更好地了解我正在做的事情的背景(因为我现在真的很困惑)。

所以假设我有一个类,看起来像这样:

class Foo{
private:
string s;
public:
Foo(string s);
};

我有一个包含此类元素的向量,如下所示:

vector<Foo> myFoos = {...};

现在,我想找到myFoos元素的索引,知道字符串的内容。以下是我想要编码的内容:

string toBeSearched = "something";
vector<Foo>::iterator it = find(myFoos.begin(),myFoos.end(),Foo(toBeSearched));
unsigned int index = distance(myFoos.begin(),it);

但我不小心弄乱了find(),并传递了一个类型为String而不是Foo:的对象

find(myFoos.begin(),myFoos.end(),toBeSearched);

然而,一切仍然如我所愿,为我提供了包含toBeSearched字符串的对象的正确位置。这超出了我的理解。当find()函数运行时,它需要检查搜索参数和向量元素之间的相等性。然而,我没有定义StringFoo之间的任何相等关系(我确实编写了==运算符的重载,以检查两个Foo之间的相等性)。因此,这样的比较是不可能的。我能想到的唯一理论是,函数搜索一个合适的构造函数,并从String(不正确的数据类型)创建一个Foo(合适的数据类型。然而,在我看来,这将是非常奇怪的行为。此外,当我碰巧传递了一个错误类型的参数时,我希望像C++这样的静态类型语言一开始甚至不会编译。std::find()内部如何处理为实现这一点而给出的参数?

C++允许"用户定义的";隐式转换。

基本上,因为有一个Foo构造函数采用string,并且您试图使用string来代替Foo,所以它决定通过将string传递到Foo的构造函数中来为您进行转换,该构造函数创建了Foo的实例。

来自CPR参考:

用户定义的转换由零个或一个非显式单参数构造函数或非显式转换函数调用组成

表达式e被称为隐式可转换为T2,当且仅当T2可以从e复制初始化,即声明T2 t=e;是格式良好的(可以编译),对于一些发明的临时t。注意,这与直接初始化(T2t(e))不同,在直接初始化中,将额外考虑显式构造函数和转换函数。

您可以将explicit关键字添加到构造函数中,以防止在隐式转换中使用它。