需要为虚函数的模板返回类型
Template return type of a function that needs to be virtual
因为以下内容是非法的:
struct A {
template <typename T>
virtual T* foo() = 0;
};
struct B : A {
template <typename T>
virtual T* foo() override {return new T;} // Simple example here.
};
template <typename T>
T* bar (A* a) {
return a->foo<T>(); // The need for the virtual method.
}
和模板只出现在返回类型中,我想到了一个(naïve?)的解决方案,使用重载:
#include <iostream>
struct Base { virtual void show() const = 0; };
struct Object : Base { virtual void show() const override {std::cout << "I am an Object.n";} };
struct Thing : Base { virtual void show() const override {std::cout << "I am a Thing.n";} };
struct Blob : Base { virtual void show() const override {std::cout << "I am a Blob.n";} };
struct A {
virtual Object* foo (Object&&) = 0;
virtual Thing* foo (Thing&&) = 0;
virtual Blob* foo (Blob&&) = 0;
};
struct B : A {
virtual Object* foo (Object&&) override {return fooHelper<Object>();}
virtual Thing* foo (Thing&&) override {return fooHelper<Thing>();}
virtual Blob* foo (Blob&&) override {return fooHelper<Blob>();}
private:
template <typename T>
T* fooHelper() {return new T;} // Simple example here.
};
template <typename T>
T* bar (A* a) {
return a->foo(T{});
}
int main() {
B* b = new B;
Base* list[] = {bar<Object>(b), bar<Thing>(b), bar<Blob>(b)};
for (const Base* x : list) x->show();
}
这个解决方案的问题是,它只有在T
没有太多类型的情况下才可行。但如果有呢?此外,当稍后引入T
的新类型时,现在存在维护问题。
...
T* fooHelper() {return new T;}
};
template <typename T>
T* create (A* a) {
return a->foo(T{});
}
A的实例对返回的T没有影响。我想这应该是一个论点。你好像还想要一个工厂。如何使用成员函数:
template < typename T, typename FactoryType,
typename MemFnType, typename ArgType >
T* create(FactoryType* f, MemFnType mfn, ArgType a)
{
return (f->*mfn)(a);
}
完整的示例:
#include <iostream>
struct Base { virtual void show() const = 0; };
struct Object : Base { virtual void show() const override {std::cout << "I am an Object.n";} };
struct Thing : Base { virtual void show() const override {std::cout << "I am a Thing.n";} };
struct Blob : Base { virtual void show() const override {std::cout << "I am a Blob.n";} };
struct Args
{
int someArg;
};
struct Factory
{
// normally 'a' would be passed to the Object constructor.
// omitted to save edits.
Object* asObject(const Args& a) { return new Object(); }
Thing* asThing(const Args& a) { return new Thing(); }
Blob* asBlob(const Args& a) { return new Blob(); }
};
template < typename T, typename FactoryType,
typename MemFnType, typename ArgType >
T* create(FactoryType& f, MemFnType mfn, ArgType& a)
{
return (&f->*mfn)(a);
}
int main() {
Args arg;
Factory f;
Base* list[] = {create<Object>(f, &Factory::asObject, arg), create<Thing>(f, &Factory::asThing, arg), create<Blob>(f, &Factory::asBlob, arg)};
for (const Base* x : list) x->show();
}
添加可构造类型只需要添加类型本身和相关的工厂函数。你甚至可以将它泛化为一个完整的模板参数列表,而不是单一的参数类型。相关文章:
- 如何获取std::result_of函数的返回类型
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 模板返回类型函数如何在C++中工作
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 在引用或指针返回类型函数上输入
- 在后面的返回类型函数语法中,auto关键字背后是否有意图
- 我可以在c++中重写字符串返回类型函数吗?