2010-10-19 95 views
3

我想创建一个基类,它将被其他对象继承,以便它们可以存储在同一个容器中。该基类将包含一个模板化方法,该方法将该函数定义为用于访问多线程系统中的缓冲区的setter或getter。我想要做这样的事,但不知道如何实施Linky。此外,我希望能够在基地的功能是虚拟的,并在派生类中定义功能,我知道你实际上不能有一个虚拟模板函数,但有没有一种方法来编码它的方式它的作用就像虚拟模板功能的概念。下面是我想如何布局的粗略示例。通过回调调用do_work方法。回调作为参数传递给线程。具有模板函数的继承类

class A { 
    template<typename R, typename P> 
    virtual R do_work(P param) = 0; 
} 

class B : public A { 
    template<void,int> // declare as setter 
    R do_work(P param){/*do something*/ return R;} 

} 

class C : public A { 
    template<int,void> // declare as getter 
    R do_work(P param){/*do something*/ return R;} 

} 
+0

在链接文章中的问题,如果第一个模板参数是“void”,如何做一些不同的事情。我认为答案是使用'boost :: enable_if'来启用 - 禁用两种替代实现中的一种。 - 但不确定,你的问题如何与之相关联。 – UncleBens 2010-10-19 14:55:57

+0

是否有可能编写一个测试R是否等于void的宏,如果没有,则使用此函数(如果不使用具有模板返回类型的函数)。 – Talguy 2010-10-19 15:06:39

+0

另一个问题:你不期待'P'是无效的,给出像'R do_work(void param)'这样的签名? – UncleBens 2010-10-19 15:10:59

回答

0

我结束了两个助手类,一个消费者类和继承基类的生产者类。基类包含一个枚举define定义派生类是否是什么功能。此枚举值是在基类构造函数调用期间设置的。帮助程序类包含我想要的虚拟do_work函数的适当版本(一个无效w /某些输入类型和一个返回类型)。当这些对象被放置在容器中时,它们作为基类被铸造,并且当它们在适当的通用线程工作者函数中被启动时,它们被转移到生产者帮助器类或者消费者帮助器类。

1

您似乎遇到了问题,A是类A中do_work的模板参数:这实际上并不合理。

R未在B或C中的任何位置定义,且您的专业化语法错误​​。

do_work不会是多态的,因为它不是虚拟的,所以如果你有一个A指针集合,它将只会调用A版本,而不是B或C,即使它们是更好的匹配。

+0

对不起,语法错误我只是不知道如何实际编码,所以我只是抛出一些东西一起来最好地说明我最终想要发生的事情。 – Talguy 2010-10-19 14:18:46

0

我所有的使用模板编程的效率和普遍性,但也许你应该有虚函数首先实现这一点。我发现在写模板版本之前干净地工作并纠正是有帮助的。如果你有一个工作的非模板函数这里

人可能会给你一个更好的答案也。

此外,如果你打算通过回调或指针调用这功能,你就失去了PERF,我认为你是试图获得与基于模板解决方案。

+0

我想我可以做这样的虚拟无效do_work(void * retrn,void * param)= 0;并在派生类中声明正确的转换和功能 – Talguy 2010-10-19 15:03:19

+0

我建议的所有内容是,在应用模板之前,首先查看功能并获得一些工作。我发现这使得它更容易,我想如果你用一个可行的解决方案编辑你的回应,你会在这里得到具体的反馈。 – Rick 2010-10-19 17:27:35

+0

使用void *可能会或可能不是正确的做法,但它可能不是,但如果是这样的话,您可能希望使其成为私有的并获得公共模板函数来执行投射,然后调用该方法。这使得该类对于用户至少是类型安全的。 – CashCow 2010-10-20 09:42:01