我有以下代码示例。我正在将指针传递给函数。当我将指针传递给函数时,函数似乎将参数初始化为某个随机数。但是,当我将变量的地址传递给函数时,它会给出预期的结果。
// find_if example
#include <iostream> // std::cout
#include <algorithm> // std::find_if
#include <vector> // std::vector
class A
{
public:
A(int i) { num = i; }
bool IsPresent (A& a) {
std::cout << "Comparing " << num << " vs " << a.num << '\n';
return (num == a.num);
};
int num;
};
int main () {
std::vector<A*> myvector;
A a1(10);
A a2(20);
A a3(30);
A a4(40);
A a(40);
const A *pa = &a;
std::cout << "pa is " << pa << '\n';
myvector.push_back(&a1);
myvector.push_back(&a2);
myvector.push_back(&a3);
myvector.push_back(&a4);
std::vector<A*>::iterator it = std::find_if (myvector.begin(), myvector.end(),
std::bind2nd(std::mem_fun(&A::IsPresent), pa));
if (it != myvector.end())
std::cout << "The first equal value is " << (*it)->num << '\n';
else
std::cout << "Cannot find a match";
return 0;
}
bool IsPresent (A& a)
在指针传递参数时将变量(A& a)
初始化为随机值,并在我传递参数时起作用?作为指针传递时,结果为
pa is 0x7b10b4d52e80
Comparing 10 vs -1261097344
Comparing 20 vs -1261097344
Comparing 30 vs -1261097344
Comparing 40 vs -1261097344
Cannot find a match
当作为参考传递时:
pa is 0x75002e9dbb30
Comparing 10 vs 40
Comparing 20 vs 40
Comparing 30 vs 40
Comparing 40 vs 40
The first equal value is 40
答案 0 :(得分:2)
std::bind2nd
is really poorly designed.
template< class F, class T >
std::binder2nd<F> bind2nd( const F& f, const T& x )
评估为:
std::binder2nd<F>(f, typename F::second_argument_type(x))
是的,那是一个C风格的演员。
我们最终会执行(A&)(pa)
,即reinterpret_cast<A&>(pa)
。
将A
指针的内存重新解释为A
的实例。
我是否说bind2nd
设计不合理?我的意思是。
C ++ 11带来了lambdas和std::bind
,它们都是头肩,身体和脚,基础和行星在bind2nd
和bind1st
之上。
有一个原因导致std::bind2nd
被弃用并从标准中移除。这只是部分的原因(也因为它依赖于它的函数参数来告诉它参数类型是什么,std::bind
没有)。
std::mem_fun
也已弃用并已从标准中删除,但此处没有任何错误。尽管如此,将其替换为std::mem_fn
,它可以完成同样的工作,但作为第一步更好。
如果std::mem_fun
盲目地将std::mem_fn
替换为std::bind2nd
而std::bind( first_arg, std::_1, second_arg )
替换second_arg
,除非std::vector<A*>::iterator it = std::find_if (
myvector.begin(), myvector.end(),
[pa](A* a){ a->IsPresent(*pa); }
);
与正确的类型匹配,否则您的代码将无法编译。它会在一堆模板垃圾邮件中这样做。
更好的是:
pa
如果您忘记取消引用a
,则会生成一个非常简单且易于阅读的编译器错误消息。
答案 1 :(得分:0)
为什么函数bool IsPresent(A&amp; a)在指针传递参数时将变量(A&amp; a)初始化为随机值,并在我传递参数时起作用?
“A&amp; a”参数被定义为引用变量,当您传递指针对象时,它会尝试将对象解释为引用。正确的方法是传递其内容。
为了改善您的解决方案,您可以将isPresent定义为bool isPresent(const A&amp; a)
为什么代码首先编译?我调用的函数需要一个引用,我传递一个指针。如果找不到函数,编译器是否应该发出警告/错误?
它可以被错误地解释为参考。因此,它可以正确编译,但执行失败。