phl*_*psy 2 c++ namespaces operator-overloading
因为我需要operator&为std::tr1::array<bool, N>我写下以下几行
template<std::size_t N>
std::tr1::array<bool, N>
operator& (const std::tr1::array<bool, N>& a,
const std::tr1::array<bool, N>& b)
{
std::tr1::array<bool, N> result;
std::transform(a.begin(), a.end(), b.begin(), result.begin(),
std::logical_and<bool>());
return result;
}
Run Code Online (Sandbox Code Playgroud)
现在我不知道我要把这个函数放在哪个命名空间中.我认为std命名空间是一个限制区域.用户只允许添加完全特化和重载的功能模板.将它放入全局命名空间不是"允许",以防止污染全局命名空间和与其他声明冲突.最后将此函数放入项目的命名空间不起作用,因为编译器不会在那里找到它.
我最擅长的是什么?我不想写一个新的数组类放入项目命名空间.因为在这种情况下,编译器将通过参数依赖名称查找找到正确的命名空间.或者这是唯一可行的方法,因为为现有类编写一个新的运算符意味着扩展它们的接口,这对于标准类也是不允许的?
我完全支持GMan和sbk,他们告诉你使用命名函数而不是运算符.与普遍认为的相反,重载运算符总是几乎是错误的,因为它几乎从未增加代码的清晰度.令人惊讶的是,很少有例外.其中包括流输入和输出运算符以及算术运算符,如果您实现类似数字的类型.(而且是多么容易的一本书教你操作符重载的那个之外?)请注意,有些人于标准库超载皱眉+(和+=,当然)为std::string出于同样的原因(和其他人一样,a+b==b+a适用于数字,但不对于字符串) - 和IMO他们确实有一点.
无论如何,如果有人想要这样做,尽管有所有建议:
当你尝试调用运算符时,编译器会尝试在调用它的命名空间,所有封闭的命名空间以及所有参数的命名空间中找到它.(后者称为参数依赖查找或Koenig查找.)参数的名称空间是std,您不能添加重载.这样就可以调用操作符所在的命名空间及其封闭的命名空间 - 包括包含所有其他命名空间的全局命名空间 - 以将操作符放入其中.
因此,如果您想要在所有警告的情况下实现它,请将其放在使用它的命名空间中.如果在多个命名空间中使用它,请将其放入包含所有这些命名空间的命名空间中.如果这是全局命名空间,那就这样吧.
哦,我提到你不应该把它作为一个重载运算符实现吗?