[英]Is it possible to fully emulate a virtual operator++(int)?
We cannot make operator++(int)
virtual
directly because of the return type problem. 由于返回类型问题,我们无法直接使
operator++(int)
virtual
。 The usual advice is to apply the curiously named Curiously Recurring Template Pattern
, which I implemented to the best of my modest understanding as follows: 通常的建议是应用奇怪的名为
Curiously Recurring Template Pattern
,我实施的最好的谦虚理解如下:
// abstract numeric type
template <typename T>
class A {
public:
virtual T& operator++() = 0;
virtual T get() const = 0;
virtual string toString() const = 0;
virtual T operator++(int) {
T old(this->get());
++*this; // calls operator++() from derived class
return old;
}
friend ostream& operator<<(ostream& os, const A& a) {
return os << a.toString();
}
virtual ~A() = 0;
};
// signed numeric type
class S : public A<S> {
public:
S(long l) : m_l(l) {}
virtual S get() const { return m_l; }
virtual string toString() const { return to_string(m_l); }
virtual S& operator++() { // no wrapping, caps at LONG_MAX
if (m_l < LONG_MAX)
++m_l;
return *this;
}
private:
long m_l;
};
// unsigned numeric type
class U : public A<U> {
public:
U(unsigned long ul) : m_ul(ul) {}
virtual U get() const { return m_ul; }
virtual string toString() const { return to_string(m_ul); }
virtual U& operator++() { // no wrapping, caps at ULONG_MAX
if (m_ul < ULONG_MAX)
++m_ul;
return *this;
}
private:
unsigned long m_ul;
};
Lots of code duplication, but at least it allows for constructs like the following to run, which is definitely a start: 很多代码重复,但至少它允许运行以下结构,这绝对是一个开始:
template <typename T>
void pinc(A<T>& a) {
cout << a++ << ' ' << a << endl;
}
int main() {
S s(LONG_MAX);
pinc(s);
U u(LONG_MAX);
pinc(u);
return 0;
}
Sadly, it does not help with things like vector<A*>
: S
and U
have no common ancestor. 可悲的是,它对
vector<A*>
<A *>之类的东西没有帮助: S
和U
没有共同的祖先。 If I derive A
from another base class, I also have to move the templated part there and the problem - ha! 如果我从另一个基类派生
A
,我还必须将模板化部分移动到那里并且问题 - 哈! - goes recursive. - 递归。
So, any suggestions? 那么,有什么建议吗?
Note to editors: Having learned my lesson, I saved the original this time. 编者注:在吸取教训后,我这次保存了原文。 :)
:)
I do not think this is possible within C++ type system, here is why: 我不认为这在C ++类型系统中是可能的,这就是为什么:
Consider the following example: Let say we somehow achieve this and have A* a
pointer to the base class from which U
and S
was derived. 考虑下面的例子:假设我们以某种方式实现了这个并且让
A* a
指向从中派生U
和S
的基类A* a
指针。 Then what will be the type of the var = (*a)++;
然后
var = (*a)++;
的类型是什么var = (*a)++;
? ? It could be either
U
or S
depending on what a
is pointing to. 它可以是
U
或S
这取决于a
指向。 But compiler need to know return type during compilation because operator++(int) return S
and U
by-value. 但编译器需要在编译期间知道返回类型,因为operator ++(int)返回
S
和U
by-value。
I see the following ways to work around this problem but they all need to change the return types of operator++(int)
in hierarchy to make them covariant (see C++ virtual function return type ): 我看到以下解决此问题的方法,但是他们都需要更改层次结构中的
operator++(int)
的返回类型以使它们协变(请参阅C ++虚函数返回类型 ):
Return pointer to a (base) class within your hierarchy 返回指向层次结构中(基类)的指针
If your types is integer types (like operator++ return char
, int
, long
for different classes) then you can make them all return enclosing type: long int
如果你的类型是整数类型(比如operator ++ return
char
, int
, long
for different classes)那么你可以让它们全部返回封闭类型: long int
Instead of returning direct values of your objects ( U
or S
) return some kind of struct that is capable of holding any of these types. 而不是返回你的对象(直接值的
U
或S
)返回某种结构,它能够持有任何这些类型的。 (see http://www.boost.org/doc/libs/1_61_0/doc/html/any.html for possible generic way to do this) (有关可能的通用方法,请参阅http://www.boost.org/doc/libs/1_61_0/doc/html/any.html )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.