2012-01-06 135 views
2

在下面的代码,我期望的输出是为什么这些模板化功能不像虚拟功能?

B 
C 

但令人沮丧的足够它是

A 
C 

有什么我可以做,以使其行为我期待的方式吗?为什么这种行为首先发生?
我辞职自己定义的stuff混入模板,并在每类中的覆盖写入,这解决了这个问题,但是是一个丑陋的黑客IMO相混合。

import std.stdio : writeln; 

class A { 
    void write() { 
     stuff(); 
    } 

    void stuff()() { 
     writeln("A"); 
    } 
} 


class B : A { 
    void stuff()() { 
     writeln("B"); 
    } 
} 

class C : A { 
    void write() { 
     stuff(); 
    } 

    void stuff()() { 
     writeln("C"); 
    } 

} 

void main (string[] args) { 
    B b = new B(); 
    b.write(); 
    C c = new C(); 
    c.write(); 
} 
+1

在'的东西()()',第一组括号将包含模板参数,在这种情况下,他们是空的,但它仍然计数。我也使用语法糖作为'b.stuff()'而不是完整的'b.stuff!()()' – 2012-01-06 02:56:13

+0

(谢谢@Jean,我已经删除了我原来的评论,因为它是完全的我想我有一次关于D模板的新东西,但我已经忘了这一切!) – 2012-01-06 03:00:17

+0

好吧,通过添加空模板参数来使模板函数成为模板的技巧可能不会出现在大多数人身上。它的主要用途是解决不允许使用非模板化函数重载模板化函数的问题。所以,从长远来看,这可能不是一个特别有用的功能。 – 2012-01-06 03:05:25

回答

3

引述online documentation

模板不能被用于非静态成员或虚拟 函数添加到类。

+0

啊谢谢,我没看到那个。是否可以接受混合模板定义内部的东西,并将该模板混合到每个子类中以实现“虚拟性”?这是迄今为止我找到的解决方案,但它并不适合我。 – 2012-01-06 02:54:24

+1

你不会得到这样的“虚拟性”。这个实现完全取决于引用类型是什么,而不是实际的对象类型。您可以使用模板将东西添加到基类。你不能重写它。你可以有一个模板化函数知道所有的派生类,通过在运行时进行投射来确定实际的对象类型是什么,然后使用特定的实现,但这很简单。但最终“可以接受”的是由你和任何人处理你的代码。 – 2012-01-06 03:02:34

+0

oops,我的意思是“虚拟性”的意思是模板函数使用字符串混合来修改类变量。如果它在基类中定义,并且子类有不同的类变量,那么它将无法编译这些语句。模板mixin解决了这个问题,因为它的上下文现在是子类,它可以访问这些新变量。你可以在这里看到我的意思:http://codereview.stackexchange.com/q/7438/8619 – 2012-01-06 03:12:06