定义一个为类获取两个引用的全局运算符和定义只接受右操作数的成员运算符之间有区别吗?
全球:
class X
{
public:
int value;
};
bool operator==(X& left, X& right)
{
return left.value == right.value;
};
Run Code Online (Sandbox Code Playgroud)
会员:
class X
{
int value;
bool operator==( X& right)
{
return value == right.value;
};
}
Run Code Online (Sandbox Code Playgroud) 我理解正常的运算符重载.编译器可以直接将它们转换为方法调用.我不太清楚 - >运算符.我正在编写我的第一个自定义迭代器,我觉得需要 - >运算符.我看了一下stl源代码并实现了我自己的代码:
MyClass* MyClassIterator::operator->() const
{
//m_iterator is a map<int, MyClass>::iterator in my code.
return &(m_iterator->second);
}
Run Code Online (Sandbox Code Playgroud)
然后我可以使用MyClassIterator的实例,如:
myClassIterator->APublicMethodInMyClass().
Run Code Online (Sandbox Code Playgroud)
看起来编译器在这里做了两个步骤.1.调用 - >()方法获取一个临时的MyClass*变量.2.在temp变量上调用APublicMethodInMyClass使用其 - >运算符.
我的理解是否正确?
在驳斥了内置运算符不参与重载决策的概念之后,我正在仔细阅读第13.5节,并注意到没有任何部分operator->*.它只是一个通用的二元运算符.
它的弟兄operator->,operator*和operator[],都要求有非静态成员函数.这排除了通常用于从对象获得引用的操作符的自由函数重载的定义.但不常见的operator->*是遗漏了.
特别是,operator[]有许多相似之处.它是二进制的(它们错过了使它成为n-ary的黄金机会),它接受左侧的某种容器和右侧的某种定位器.除了禁止免费功能外,其特殊规则部分13.5.5似乎没有任何实际效果.(这种限制甚至排除了对交换性的支持!)
因此,例如,这是完全合法的:
#include <utility>
#include <iostream>
using namespace std;
template< class T >
T &
operator->*( pair<T,T> &l, bool r )
{ return r? l.second : l.first; }
template< class T >
T & operator->*( bool l, pair<T,T> &r ) { return r->*l; }
int main() {
pair<int, int> y( 5, 6 );
y->*(0) = 7;
y->*0->*y = …Run Code Online (Sandbox Code Playgroud) 我有一个重载的C++类,operator[]数组下标/括号运算符.这在我班级以外非常方便,在那里我可以写foo[bar].但是,当我在我的类中实现方法时,我无法弄清楚如何使用这种表示法.
我知道我可以写operator[](bar),this->operator[](bar)但这些都相当笨重,并且首先会带走操作员的许多便利.(我也知道我可以只添加调用操作的新方法.)有没有一种方法我可以写this[bar]或this->[bar]或一些类似的好看?
注意:这个问题也可能适用于许多一元运算符(例如,我如何foo++从课堂内调用?),但我个人只关心operator[].
编辑:我发布后很快意识到我可以使用(*this)[bar].到目前为止,所有答案都表明了这一点.还有其他选择吗?
Python文档清楚地说明了x==y调用x.__eq__(y).然而,似乎在许多情况下,情况正好相反.它记录了何时或为何发生这种情况,以及如何确定我的对象__cmp__或__eq__方法是否会被调用.
编辑:只是为了澄清,我知道这__eq__是在优先考虑__cmp__,但我不清楚为什么y.__eq__(x)被优先调用x.__eq__(y),当后者是文档状态将发生.
>>> class TestCmp(object):
... def __cmp__(self, other):
... print "__cmp__ got called"
... return 0
...
>>> class TestEq(object):
... def __eq__(self, other):
... print "__eq__ got called"
... return True
...
>>> tc = TestCmp()
>>> te = TestEq()
>>>
>>> 1 == tc
__cmp__ got called
True
>>> tc == 1
__cmp__ got called
True
>>>
>>> 1 == te …Run Code Online (Sandbox Code Playgroud) 这里的答案提供了一个手工引用的参考,你想要__ne__返回的东西不仅仅是逻辑逆__eq__,但我无法想象任何这样的情况.任何例子?
在特定命名空间中创建库时,为该命名空间中的类提供重载操作符通常很方便.看来(至少用g ++),重载的运算符可以在库的命名空间中实现:
namespace Lib {
class A {
};
A operator+(const A&, const A&);
} // namespace Lib
Run Code Online (Sandbox Code Playgroud)
或全局命名空间
namespace Lib {
class A {
};
} // namespace Lib
Lib::A operator+(const Lib::A&, const Lib::A&);
Run Code Online (Sandbox Code Playgroud)
从我的测试来看,它们似乎都运行良好.这两个选项之间是否存在实际差异?两种方法都更好吗?
在我刚刚进行的测试之前,我相信只有构造函数不会在C++中继承.但显然,任务operator=不是......
operator+=,operator-=...?事实上,我在做一些CRTP时遇到了这个问题:
template<class Crtp> class Base
{
inline Crtp& operator=(const Base<Crtp>& rhs) {/*SOMETHING*/; return static_cast<Crtp&>(*this);}
};
class Derived1 : public Base<Derived1>
{
};
class Derived2 : public Base<Derived2>
{
};
Run Code Online (Sandbox Code Playgroud)
是否有任何解决方案可以使其工作?
编辑:好的,我已经解决了这个问题.为什么以下不起作用?如何解决问题?
#include <iostream>
#include <type_traits>
// Base class
template<template<typename, unsigned int> class CRTP, typename T, unsigned int N> class Base
{
// Cast to base
public:
inline Base<CRTP, T, N>& operator()()
{
return *this;
}
// Operator =
public: …Run Code Online (Sandbox Code Playgroud) 考虑我有以下最小代码:
#include <boost/type_traits.hpp>
template<typename ptr_t>
struct TData
{
typedef typename boost::remove_extent<ptr_t>::type value_type;
ptr_t data;
value_type & operator [] ( size_t id ) { return data[id]; }
operator ptr_t & () { return data; }
};
int main( int argc, char ** argv )
{
TData<float[100][100]> t;
t[1][1] = 5;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GNU C++给了我错误:
test.cpp: In function 'int main(int, char**)':
test.cpp:16: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than …Run Code Online (Sandbox Code Playgroud) 假设您正在编写一个接受被std::initializer_list调用list的函数,并且该函数需要随机访问其list元素.写list[i]代替是方便的list.begin()[i].那么为什么不std::initializer_list提供定义operator[]呢?
我想不出任何operator[]返回const T&不明确的情况.效率在这里似乎不是问题,因为std::initializer_list<T>::iterator别名const T*,显然是随机访问迭代器.
c++ ×8
python ×2
c++11 ×1
comparison ×1
crtp ×1
inheritance ×1
iterator ×1
namespaces ×1
templates ×1