具有模板容器的协变返回类型
Covariant Return Type With Template Container
本文关键字:返回类型 更新时间:2023-10-16
是否可以进行以下工作?基本上,我希望 Ptr 成为 Ptr 可接受的返回类型替代品。
template<typename T>
class Ptr {
public:
explicit Ptr (T * ptr) : ptr(ptr) {}
T * ptr;
};
class A {
virtual Ptr<A> foo () {
return Ptr<A>(NULL);
}
};
class B : public A {
virtual Ptr<B> foo () { // BAD! Ptr<B> is not compatable
return Ptr<B>(NULL);
}
};
您可以使用奇怪的重复模板将虚拟函数重载替换为模板函数返回。以下文章可能会有所帮助:
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
另请检查以下代码:
template <class C_>
class A_Base {
Ptr<C_> foo() {
return static_cast<C_*>(this)->foo_impl();
}
}
class A : public A_Base<A> {
Ptr<A> foo_impl() { return Ptr<A>(NULL); }
}
class B : public A_Base<B> {
Ptr<B> foo_impl() { return Ptr<B>(NULL); }
}
根据标准:
重写函数的返回类型应与被重写函数的返回类型相同,或与函数的类协变。如果函数 D::f 覆盖函数 B::f,则函数的返回类型在满足以下条件时是协变的:
- 两者都是指向类的指针或对类的引用 返回类型 B::f 中的类与返回类型 D::f
- 中的类是同一类,或者是返回类型 D::f 中类的明确直接或间接基类,可在 D 中访问
- 这两个指针或引用具有相同的 CV 限定,并且返回类型 D::f 中的类类型与返回类型 B::f 中的类类型具有相同的 CV 限定或更少的 CV 限定。
因此,在您的示例中,返回类型并不是真正的协变(它们不是指针也不是引用),而且Ptr<B>
和Ptr<A>
是不相关的类型。
因此,将 foo 保持虚拟并在 A 中返回 Ptr<A>
,在 B 中返回Ptr<B>
是不可能的。如果你可以/愿意放弃虚拟,那么你就可以在Cem Kalyoncu的提议或其变体中使用一些东西。
你可以尝试这样的事情:
template<class T> class Ptr
{
...
};
template<class T> class A
{
virtual Ptr<T> foo();
};
class B : public A<B>
{
virtual Ptr<B> foo();
};
相关文章:
- 如何获取std::result_of函数的返回类型
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 为什么返回类型中需要typename?C++
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 推导 std::vector::back() 的返回类型
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 基于返回类型的转换和过载扣除
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*