gpt4 book ai didi

c++ - 为什么在模板中调用基类的运算符?

转载 作者:太空狗 更新时间:2023-10-29 20:54:44 25 4
gpt4 key购买 nike

为什么B::operator() 在下面的程序中同时为BD 调用?

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

class B {
public:
virtual ~B() {}
virtual bool operator()(int a, int b) { return a < b; }
};

class D : public B {
public:
bool operator()(int a, int b) override { return a > b; }
};

void f(B& b, std::vector<int>& v)
{
std::sort(v.begin(), v.end(), b);
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}

int main()
{
const std::vector<int> v{5, 3, 8, 1, 7};

std::vector<int> vb(v);
B b;
f(b, vb);

std::vector<int> vd(v);
D d;
f(d, vd);

return 0;
}

如果我将 std::sort(v.begin(), v.end(), b) 更改为:

std::sort(v.begin(), v.end(),
[&](int x, int y){ return b.operator()(x, y); });

然后 f(d, vd) 按预期向后排序。

我最好的理解是 std::sort(v.begin(), v.end(), b) 使用 &B::operator() 而不是b.operator()。虽然我找不到明确的解释,而且它似乎并不完全合乎逻辑,因为编译器应该能够看到 B 有一个 vtable。

最佳答案

std::sort 的签名:

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

参数comp 将在此处按值传递,因此对于f(d, vd);d 将为slicing copiedB 然后 B::operator() 将被调用。

您可以使 f() 成为模板函数。

template <typename COMP>
void f(COMP& b, std::vector<int>& v)
{
std::sort(v.begin(), v.end(), b);
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}

其他建议:最好让B::operator()D::operator()成员函数为常量,改变参数类型b 到 const 引用。

LIVE

关于c++ - 为什么在模板中调用基类的运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38262791/

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