我正在实现自己boost::array
的娱乐和教育变体,我只是想知道:比较两个不同大小的数组是否会产生错误,还是应该是类型错误?
array<int, 3> a = {1, 2, 3};
array<int, 5> b = {1, 2, 3, 4, 5};
a == b // <--- false or type error?
我正在实现自己boost::array
的娱乐和教育变体,我只是想知道:比较两个不同大小的数组是否会产生错误,还是应该是类型错误?
array<int, 3> a = {1, 2, 3};
array<int, 5> b = {1, 2, 3, 4, 5};
a == b // <--- false or type error?
它应该是一个类型错误。使用它的人boost::array
选择它std::vector
是因为他们希望在编译时而不是运行时进行评估(和失败)。
这个问题不能有一个普遍的答案。这取决于比较数组的代码的业务逻辑。
但总的来说,如果我不知道比较数组的业务逻辑是什么,我会返回false
. 如果它们的大小不同,则数组是不同的。
如果您的数组未公开诸如 之类的基类array<int>
,则会产生类型错误,因为您的类的函数基于强类型。如果确实允许大小的多态性,则返回 false。
更重要的是,拥有一个在所有情况下总是返回相同值的运算符有什么好处?
在语言中,不同的模板实例是不相关的类型。这意味着从技术上讲,最简单的事情就是 boost::array 所做的:忽略这个问题,如果你尝试比较不同的大小,编译器会大喊大叫。
我倾向于回答这取决于您正在建模的域,但鉴于数组大小是编译时间常数,用户应该知道两个数组是不同的,甚至无需尝试比较。即使在模板代码中,只要有一个大小参数,一切都会自行到位。
我认为这个问题比唯一的==
运营商更普遍。
运算符与==
密切相关,!=
并且可能与<
、和相关联。>
<=
>=
定义应该在所有这些中保持一致,即可以比较两个不同大小的数组(无论使用什么比较),或者不是。
我怀疑两者都可能有用:
但是只有一个在编译期间产生警告,另一个暗示您希望在运行时(通过测试)发现问题。因此,我将提供一个“安全”运算符重载,以及一个更详细的“软”比较方法:
template <typename T, size_t M, size_t N>
bool soft_equal(array<T,M> const& lhs, array<T,N> const& rhs)
{
if (M != N) { return false; }
// comparison logic
}
template <typename T, size_t M>
bool operator==(array<T,M> const& lhs, array<T,M> const& rhs)
{
return soft_equal(lhs,rhs); // count on the compiler to eliminate the 'if'
}
通过这种方式,您可以两全其美,我认为:
指导方针:做对容易,做错很难
在 C++ 中,array<int, 3>
和array<int, 5>
是不同的类型,就像std::vector<int>
和std::list<int>
是不同的类型一样。它们是从同一个模板实例化的这一事实几乎是无关紧要的。
现在,您可以将两者都视为序列,然后进行比较就有意义了。然而,为此,通常使用迭代器。
不同大小的数组不相等,在您的情况下,您在编译时就知道了。不要为不同的大小实现相等运算符;这是没有意义的!你知道他们已经不平等了!