具有非类型模板参数的多态性
polymorphism with non-type template parameters
我希望这不会过于复杂。我试着在互联网上搜索了一段时间,虽然我发现了很多关于模板、继承等的问答,但我发现的资源都没有涉及这个特定的问题:
我想为std::vector<T>
创建一个包装器,它将只创建类型为std::vector<MyClass>
或其任何继承类的向量。
这基本上看起来像:
Class Base;
Class Derived : Base;
template <Base T> class myVector{
public:
void add(T);
protected:
std::vector<T> list;
}
目标是能够拥有一个具有以下行为的库:
Base A;
Derived D;
int i;
myVector<A> AVector; // This should work
myVector<D> DVector; // This should work
myVector<i> iVector; // This should NOT work
AVector.add(A); // This should work
AVector.add(D); // This should work (through polymorphism)
DVector.add(D); // This should work
DVector.add(A); // This should not work
有人能对以上问题/例子发表评论吗?我的最终目标是在c++中实现我自己的基本事件处理。在这种情况下,A将是c#EventArgs的类似物。B将允许特定的EventArgs类型。我毫不怀疑Boost等人也有类似的功能,但我想暂时避开这条路线。
在实践中,代码的工作原理类似于(在某种程度上基于我在互联网上找到的教程):
template<EventArgs arg> class Event{
typedef void (*fptr)(arg);
std::vector<fptr> listeners;
}
void notifylisteners(arg){
for (typename std::vector<fptr>::iterator iter = listeners.begin(); iter != listeners.end; ++iter)
(**iter)(arg); // there should be a check for a valid reference, in case one of the function pointers becomes invalid
申报
Event<myEventHandlerType> myEvent;
将有效地起到与C#代码相同的作用:
public event myEventHandlerType myEvent;
由于对std::vector的依赖,此实现需要模板。在这里使用非类型参数模板(如果有效的话)的好处是,它会强制将特定eventArg参数类型的使用传递给所有注册的处理程序,并且在编译过程中错误会失败。
如有任何想法或意见,我们将不胜感激。
Michael
如果您使用C++11,您可以访问std::is_base_of<>和static_assert()
当myVector传递了一个无法强制转换为Base的类型时,可以让编译器给您一个错误。
#include <type_traits>
class Base
{};
class Derived : public Base
{};
template <class T>
class Foo
{
public:
Foo()
{
static_assert (std::is_base_of<Base,T>::value, "Error: Type T not derived from Base");
}
};
class Lol
{
};
Foo<Derived> foo1;
Foo<Lol> foo2; //Static assert fails
(请参阅此处的编译器输出http://ideone.com/NAXSA)
如果你没有C++11支持,那么你就有更多的跑腿工作,但这仍然可以完成。请参阅此处https://stackoverflow.com/a/4532302/564944
我希望我能正确理解你的描述。C++实现这一点的方法不是通过继承,也不会"强制"传入从A
继承的类型。相反,使用鸭子类型:如果它看起来像鸭子,走路像鸭子,嘎嘎叫像鸭子,那么它就是鸭子,而不管它的"官方"类型是什么。
具体地说,myVector<T>
将简单地接受任何类型的T
。如果您试图对T
对象执行它不支持的操作,例如用特定的arg
调用它,它将在编译时失败。
当然,最好记录T
需要支持的操作的签名——本质上是它实现的接口。
(附带说明:C++0x"概念"的概念本可以让您在代码中表达这一点,但它已从标准中删除。)
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- 在多态性中重新定义功能(虚拟),具有不同数量的参数
- 具有不同参数的多态性
- 为什么说C++不支持参数多态性
- 具有非类型模板参数的多态性
- C++ 多态性和可变参数模板
- C++,多态性与函数参数的模板化
- 成员变量多态性和参数引用
- c++对象参数:多态性,值语义,对象生命周期
- gtest类型参数化的多态性
- 具有可变函数参数的C++多态性