C++ std::find是否隐式修复无效参数?
所以我有一个非常奇怪的情况,我的一个程序正在工作,而据我所知,它根本不可能工作。因此,这个问题只是因为我想更好地了解我正在做的事情的背景(因为我现在真的很困惑) 假设我有一个类似这样的类:C++ std::find是否隐式修复无效参数?,c++,iterator,stdvector,C++,Iterator,Stdvector,所以我有一个非常奇怪的情况,我的一个程序正在工作,而据我所知,它根本不可能工作。因此,这个问题只是因为我想更好地了解我正在做的事情的背景(因为我现在真的很困惑) 假设我有一个类似这样的类: class Foo{ private: string s; public: Foo(string s); }; vector<Foo> myFoos = {...}; 我有一个包含此类元素的向量,如下所示: class Foo{ private: string s; public:
class Foo{
private:
string s;
public:
Foo(string s);
};
vector<Foo> myFoos = {...};
我有一个包含此类元素的向量,如下所示:
class Foo{
private:
string s;
public:
Foo(string s);
};
vector<Foo> myFoos = {...};
但是我不小心弄乱了find()
,传递了一个String
类型的对象,而不是Foo
:
find(myFoos.begin(),myFoos.end(),toBeSearched);
然而,一切仍然像我希望的那样工作,给了我包含待搜索字符串的对象的正确位置。这超出了我的理解,这是为什么。当运行find()
函数时,需要检查搜索参数和向量元素之间是否相等。然而,我没有在String
和Foo
之间定义任何相等关系(我确实编写了==操作符的重载来检查两个Foo
之间的相等性)。因此,这样的比较是不可能的。我能想到的唯一理论是,函数搜索合适的构造函数,并从字符串(不正确的数据类型)创建Foo
(合适的数据类型)。然而,在我看来,这将是非常奇怪的行为。此外,我希望像C++这样的静态类型语言在我遇到像这样错误类型的参数时,甚至不会首先编译。
std::find()
如何处理为实现此目的而提供的参数?C++允许“用户定义”隐式转换
基本上,因为有一个Foo
构造函数接受string
,并且您试图使用string
代替Foo
,所以它决定通过将string
传递到Foo
的构造函数中来为您进行转换,该构造函数创建了Foo
的实例
发件人:
用户定义的转换由零个或一个非显式单参数构造函数或非显式转换函数调用组成
当且仅当T2可以从e复制初始化时,表达式e被称为隐式转换为T2,即声明T2 t=e;是格式良好的(可以编译),对于某些人来说。请注意,这与直接初始化(t2t(e))不同,后者将额外考虑显式构造函数和转换函数
您可以将explicit
关键字添加到构造函数中,以防止在隐式转换中使用它。但我必须承认,该引用的一部分让我感到困惑:“…表达式e被称为隐式转换为T2,当且仅当T2可以从e复制初始化时,即声明T2 t=e”格式良好“代码>将是有效的。OP描述的行为一定是因为隐式转换,但我不明白为什么一开始就允许这样的转换。我还没有测试过它,但我认为隐式转换在每次比较中都会发生。因为find的定义是(根据[):templateInputIt find(InputIt first,InputIt last,const T&value)
std::string
将与T
完美匹配,因此在传递字符串时不会发生转换。只有在调用操作符==
内部find
时,转换才会成为必需的,从而对每个元素执行。@sv90正确:std::find
推断模板参数t是std::string
,但在find
中,重载解析表达式,如*iter==value
finds操作符==(const Foo&,const Foo&)<代码> >因为<代码>字符串可以隐式转换为<代码> Foo。@ AsCufer-DaMn,C++是混淆的。它表示我的10K答案是我只懂的东西。很高兴你们能验证它。<代码> T t= x;< /C> >定义为<代码> t t= t(x)如果T
与x
的类型无关。这与您可以编写std::string s=“some string”
的原因相同,即使“some string”
不是std::string
。类似地,float f=1;