[英]Overriding typedefs in C++
I have a generic struct 我有一个通用的结构
template<typename X, typename Y>
struct S
{
};
Then there is an abstract class which returns shared pointer to above struct in a pure virtual function. 然后有一个抽象类,它在纯虚函数中返回上面struct的共享指针。 One of the derived classes also implements this function but needs to return pointer to S with different instantiated type: 其中一个派生类也实现了这个函数,但是需要使用不同的实例化类型返回指向S的指针:
typedef boost::shared_pointer<S<double, double>> BPtr;
class BaseClass
{
public:
BPtr Func() = 0;
};
typedef boost::shared_pointer<S<double, std::tuple<double, double>>> Dptr;
class DerivedClass : public BaseClass
{
public:
DPtr Func() {}
}
Ideally I would like to be able to return an override typedef in the derived class but can't do that in C++. 理想情况下,我希望能够在派生类中返回覆盖typedef,但不能在C ++中执行此操作。
How do I fix this dilemma? 我该如何解决这个难题?
Firstly, the smart pointers: They don't have a common baseclass (just as vector<baseclass>
is not a baseclass of vector<derived>
), so covariant return types won't work. 首先,智能指针:它们没有共同的基类(就像vector<baseclass>
不是vector<derived>
的基类),因此协变返回类型将不起作用。
Secondly, even if you replaced the smart pointers with raw pointers, different instantiations of a class template don't share a common base either (like vector and smart pointers), so you're out of luck. 其次,即使你用原始指针替换了智能指针,类模板的不同实例也不会共享一个共同的基础(如向量和智能指针),所以你运气不好。
Note that different instantiations of class templates can actually derive from one another, so if S<double,double>
was a baseclass for S<double,tuple<double,double>>
, you could use covariant returns, but that seems like a wonky approach. 请注意,类模板的不同实例化实际上可以相互派生,所以如果S<double,double>
是S<double,tuple<double,double>>
的基类,则可以使用协变返回,但这看起来像一个不稳定的做法。
In summary, I think you should describe why you think that an S<T,tuple<T,T>>
could be treated like an S<T,T>
, which seems the underlying assumption in your code. 总而言之,我认为您应该描述为什么您认为S<T,tuple<T,T>>
可以被视为S<T,T>
,这似乎是代码中的基本假设。
Whatever DerivedClass::Func
returns must be a subtype of what BaseClass::Func
returns. 无论DerivedClass::Func
返回什么,必须是BaseClass::Func
返回的子类型。 Otherwise, DerivedClass
is obviously not a specialization of BaseClass
. 否则, DerivedClass
显然不是 BaseClass
。
What makes you build this inheritance relationship in the first place? 是什么让你首先建立这种继承关系? Without it, you could just make the return type of Func
a template parameter. 没有它,您可以只将Func
的返回类型作为模板参数。
First of all, I think you probably meant to make Base::Func()
a virtual
member function. 首先,我认为你可能想让Base::Func()
成为一个virtual
成员函数。
class BaseClass
{
public:
virtual BPtr Func() = 0;
// ^^^ Missing
};
Re: 回覆:
Ideally I would like to be able to return an override
typedef
in the derived class but can't do that in C++. 理想情况下,我希望能够在派生类中返回覆盖typedef
,但不能在C ++中执行此操作。
You can override the typedef
in the derived class but that does not necessarily make it a valid return type of the virtual
member function. 您可以覆盖派生类中的typedef
,但这并不一定使其成为virtual
成员函数的有效返回类型。
For instance, if I have: 例如,如果我有:
struct Foo
{
typedef int return_type;
virtual return_type func() = 0;
};
struct Bar : Foo
{
typedef double return_type;
virtual return_type func() override { return 1.0; }
};
You should get a compiler error. 您应该收到编译器错误。 Just because I use return_type
in both the base class and the derived class does not make them suitable to be used as the return type of the virtual
member function. 仅仅因为我在基类和派生类中都使用了return_type
,这使得它们不适合用作virtual
成员函数的返回类型。
The return type in an overridden implementation can be covariant type , not any old type. 重写实现中的返回类型可以是协变类型 ,而不是任何旧类型。 A typedef
is just an alias. typedef
只是一个别名。 It's not a true type. 这不是真正的类型。
Re: 回覆:
How do I fix this dilemma? 我该如何解决这个难题?
You'll have to rethink your return types. 您必须重新考虑您的退货类型。 You cannot use boost::shared_pointer<S<double, std::tuple<double, double>>>
for the return type in the derived class when the return type in the base class is boost::shared_pointer<S<double, double>>
. 当基类中的返回类型为boost::shared_pointer<S<double, double>>
时,不能对派生类中的返回类型使用boost::shared_pointer<S<double, std::tuple<double, double>>>
boost::shared_pointer<S<double, double>>
。
An (abstract) base class with virtual functions is used to provide the interface for the derived classes. 具有虚函数的(抽象)基类用于为派生类提供接口。 You cannot have the same function return different (more precisily non-covariant) things depending on the derived type because the user has a contract with the base class. 根据派生类型,您不能使用相同的函数返回不同的(更精确的非协变)事物,因为用户与基类具有契约。
If I have a 如果我有
Base * p = /* get whatever derived instance here */;
it might very well be the case that I cannot even tell what actual derived type is hidden behind the pointer. 很可能就是我甚至无法分辨指针背后隐藏的实际派生类型。
Therefore, if Func
is declared as 因此,如果Func
被声明为
boost::shared_ptr<S<double, double>> Func();
I'd expect it to return boost::shared_ptr<S<double, double>>
and not something that depends on the actual derived type. 我希望它返回boost::shared_ptr<S<double, double>>
而不是依赖于实际派生类型的东西。
The reason is simple: If some derived type would be added that returns something that is incompatible with my code it would break my implementation with out the interface being changed at all. 原因很简单:如果某些派生类型将被添加返回的东西,是我的代码,将打破我的实现与出接口所发生任何变化不兼容。
It would work however, if S<double, std::tuple<double, double>>
would derive from S<double, double>
. 但是,如果S<double, std::tuple<double, double>>
将从S<double, double>
派生,它将起作用。
You cannot get around that restriction with typedefs because they are just alias names for the types they refer to. 您无法使用typedef解决该限制,因为它们只是它们引用的类型的别名。 With a typedef like using BPtr = boost::shared_ptr<S<double, double>>;
使用类似于using BPtr = boost::shared_ptr<S<double, double>>;
的typedef using BPtr = boost::shared_ptr<S<double, double>>;
, this declaration: ,这个声明:
BPtr foo();
is equivalent to 相当于
boost::shared_ptr<S<double, double>> foo();
it is just less typing involved if the typedef is used repeatedly. 如果重复使用typedef,那么只需要更少的输入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.