gpt4 book ai didi

c++ - 为什么标准容器使用函数模板而不是非模板 Koenig 运算符

转载 作者:IT老高 更新时间:2023-10-28 21:34:04 25 4
gpt4 key购买 nike

这个问题的灵感来自 Issue with std::reference_wrapper .比如说,operator<对于 std::vector .它被定义为函数模板

template< class T, class Alloc >
bool operator<( const vector<T,Alloc>& lhs,
const vector<T,Alloc>& rhs );

因此,函数参数到相应函数参数类型的隐式转换被拒绝(主要是因为它的模板性质)。这大大降低了std::reference_wrapper 的实用性和便利性。 .例如,您不能使用 std::sortstd::vector<std::reference_wrapper<std::vector<int>>> .

另一方面,所有问题都只有在 operator< 的情况下才能解决。被定义为非模板 Koenig 运算符,如

template <...>
class vector ... {
friend bool operator<(const vector& a, const vector& b) {...}
};

我想知道为什么标准库采用了前一种方法而不是这种方法?

最佳答案

考虑以下代码 (A.h):

template <class T>
class A {
public:
T m_x;

friend bool operator<(const A & lhs, const A & rhs) {
return lhs.m_x < rhs.m_x;
}
};

还有main.cpp:

#include "A.h"

namespace buddy {
bool operator<(const A<double> & lhs, const A<double> &rhs) {
return lhs.m_x > rhs.m_x;
};
}
using namespace buddy;
int main(int argc, char ** argv) {

A<double> a1;
A<double> a2;

a1 < a2;

return 0;
}

此代码无法编译:

main.cpp:14:5: 错误:‘operator<’的重载不明确(操作数类型为‘A’和‘A’) a1 < a2;

原因当然是两个运算符< 都是完全匹配的。另一方面,如果我们将第一个 operator< 更改为(在类外定义):

template <class T>
bool operator<(const A<T> & lhs, const A<T> & rhs) {
return lhs.m_x < rhs.m_x;
}

编译器停止提示:现在是完全匹配和函数模板之间的竞争,所以使用完全匹配。

如果 operator< 是以您建议的方式定义的,那么 std::vector 的用户将没有合理的方法来重新定义 operator< 的行为,除非自己专门化 std::vector,这是一个还有很多工作。

总之,标准编写者选择使重载 operator< 比提供在某些情况下可能更有用的 operator< 更容易。我认为他们做出了正确的选择。

关于c++ - 为什么标准容器使用函数模板而不是非模板 Koenig 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30265627/

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