编写函数符合模板定义的函数原型

时间:2015-08-30 16:25:52

标签: d

令我高兴的是,我发现D已取得进展,现在实际上是在Windows 64位上运行。它甚至还有一个Visual Studio集成,在我玩新玩具几个小时后,它似乎可以工作。

所以,显然我刚开始玩D作为一种语言而且是D中的血腥新手。

在下面的代码中,我的目标是在模板中定义函数原型,然后将函数编写为main()的子函数,这些子函数符合这些原型。但编译器抱怨并且现在我无法找到如何使它正确(可能是简单的语法问题)。

我得到的编译器错误是:

  

main.d(90):错误:函数main.Actor!(int,int).Worker(持续时间超时,bool函数(int)timeoutHandler,bool函数(int,int)messageHandler,int context)不可调用使用参数类型()

     

main.d(90):错误:函数main.main.W1OnTimeout(int context)不能使用参数类型调用()

     

main.d(90):错误:函数main.main.W1OnMessage(int context,int message)不能使用参数类型调用()

     

构建Debug \ ConsoleApp1.exe失败!

import std.stdio;
import core.time;
import std.socket;
import std.concurrency;
import core.thread;

enum SystemMessage
{
    Shutdown,
    Terminate,
    Ping,
    Enable,
    Disable
}

template Actor(C,M) 
{
    // TimeoutHandler implementations always return true 
    // unless the worker shall terminate.
    alias TimeoutHandler = bool function(C);
    // MessageHandler implementations always return true 
    // unless the worker shall terminate.
    alias MessageHandler = bool function(C,M);

    void 
    Worker
        ( Duration timeout
        , TimeoutHandler timeoutHandler
        , MessageHandler messageHandler
        , C context
        )
    {
        bool running = true;
        bool enabled = true;
        while(running)
        {
            if( true == std.concurrency.receiveTimeout
                    (timeout,
                     (M message) 
                     {
                         if(enabled)
                         {
                            if(!messageHandler(context,message) )
                            {
                               running = false; 
                            }
                         }
                     },
                     (SystemMessage message)
                     {  
                         switch(message)
                         {
                             case SystemMessage.Shutdown: running = false; break;
                             case SystemMessage.Terminate: running = false; break;
                             case SystemMessage.Enable: enabled = true; break;
                             case SystemMessage.Disable: enabled = false; break;
                             case SystemMessage.Ping: /* TODO: supervisor... */; break;
                             default: break;
                         }
                     }
                     ))
            {
            }
            else
            {
                if(!timeoutHandler(context))
                {
                    running = false;
                }
            }
        }
    }
}

alias IntIntActor = Actor!(int,int);


int main(string[] argv)
{
    // The signatures of the next 2 functions conform to the function 
    // declarations, given in Actor template (IntIntActor). 
    // How to write them so it works?
    bool W1OnTimeout(int context)
    {
        writeln("W1OnTimeout()");
        return true;
    }
    bool W1OnMessage(int context,int message)
    {
        writefln("W1OnMessage: context = %d, message = %d", context, message);
        return true;
    }
    // Do I need some special syntax here? Like e.g. &W1OnTimeout ? Or a cast?
    auto w1 = spawn(IntIntActor.Worker,1000.msecs,W1OnTimeout,W1OnMessage,1);
    for(int i = 0; i < 10; i++)
    {
        send(w1,i);
    }
    Thread.sleep(5000.msecs);
    send(w1,SystemMessage.Shutdown);
    thread_joinAll();
    return 0;
}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

你几乎在评论中给出了答案:

// Do I need some special syntax here? Like e.g. &W1OnTimeout ? Or a cast?

&W1OnTimeout就是这样;还有&IntIntActor.Worker&W1OnMessage

它仍然无法编译,因为&W1OnTimeout&W1OnMessage被视为委托,但Worker需要函数指针。标记嵌套函数static并且它可以工作:

static bool W1OnTimeout(int context)
{
    ...
}
static bool W1OnMessage(int context,int message)
{
    ...
}

或者,在main之外定义它们。