C++多态模板类,模板类型对象的实例化
Posted
技术标签:
【中文标题】C++多态模板类,模板类型对象的实例化【英文标题】:C++ Polymorphic template class, instantiation of template type object 【发布时间】:2020-05-20 17:25:39 【问题描述】:我有以下情况,我想实例化一个模板类型的对象。 我希望模板类型对象的实例化依赖于“实例化器”类。
template <class T>
class Base
public:
Base()
void do_something()
T obj = this->Test();
// do something with object
virtual T Test()
return T(5);
;
template <class T>
class Derived : public Base<T>
public:
Derived() : Base<T>()
virtual T Test()
return T(5, 6);
;
class Test1
public:
Test1(int x)
;
class Test2 : public Test1
public:
Test2(int x, int y) : Test1(x)
;
稍后在我的代码中,我想使用 Base 或 Derived 对象。
它们在函数 do_something()
中对模板类型对象 (obj
) 执行操作。
我想让obj
的实例化依赖于实现
Test()
函数。
Base
应该只适用于 Test1
类型的对象或具有相同构造函数的 Test1
的派生类。
Derived
应该只适用于与 Test2
具有相同构造函数的对象。
Base<Test1>(); // works
Base<Test2>(); // doesn't work, but should not work by my design and throw a compile error
Derived<Test1>(); // same
Derived<Test2>(); // should work, but doesn't,
// since Base::Test() still exists, but cannot be compiled due to wrong constructor of T
有没有办法实现所描述的行为? 或者我可以进行设计更改吗?
【问题讨论】:
坦率地说,您的代码中充满了拼写错误。目前尚不清楚该代码应该实现什么。请解释它或给出一个输出示例并告诉我们所需的输出 请提供minimal reproducible example。你修正了一些错别字,但还是太多了。 你是对的,我在快速写问题时犯了很多错别字。我已经修复了它们并写了我想要的行为的一个小解释。 【参考方案1】:对于任何T
,您可以将 Base 更改为正确:
template <class T>
class Base
public:
Base()
void do_something()
T obj = this->Test();
// do something with object
virtual T Test()
if constexpr (std::is_constructible_v<T, int>)
return T(5);
throw std::runtime_error("should not be called");
;
但是
Base<Test2>();
会编译但会在运行时抛出。
拆分并派生两个似乎更好:
template <class T>
class Base
public:
Base() = default;
virtual ~Base() = default;
void do_something()
T obj = this->Test();
// do something with object
virtual T Test() = 0;
;
template <class T>
class Derived : public Base<T>
public:
Derived() : Base<T>()
T Test() override return T(4);
;
template <class T>
class Derived2 : public Base<T>
public:
Derived() : Base<T>()
T Test() override return T(5, 6);
;
【讨论】:
感谢您的回答。这似乎是一个很好的解决方案。抽象基础也是一个好主意。我最初希望Derived
可以与相同的模板类型完全互换,但这永远不会奏效。我的意思是,我的示例甚至被设计为不允许这样做。所以我可能会使用你的解决方案。以上是关于C++多态模板类,模板类型对象的实例化的主要内容,如果未能解决你的问题,请参考以下文章
C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译