当前位置:  开发笔记 > 编程语言 > 正文

具有不同调用约定的可调用对象

如何解决《具有不同调用约定的可调用对象》经验,为你挑选了0个好方法。

目前我正在为不同的调用约定(__stdcall,__ cdecl,__ fastcall等)构建仿函数(可调用类型).使用包装器,我将能够做到这样的事情:

void __stdcall foo(int arg)
{
    std::printf("arg: %i\n", arg);
}

int main(int, char**)
{
    Function v{foo};
    v(1337);

    return EXIT_SUCCESS;
}

目前,我为__stdcall调用约定构建了一个包装器,只要指定了正确的参数并传入了正确的参数,就可以调用任何__stdcall函数.该类如下所示:

template 
class Function
{
    // NOTE: This version of my callable types
    // only supports the __stdcall calling
    // convention. I need support for __cdecl,
    // __fastcall and also __thiscall.
    using return_t = ReturnT;
    using callable_t = return_t(__stdcall*)(Args...);

private:
    callable_t mCallable;

public:
    template 
    Function(FuncT const &func) :
        mCallable(func)
    {
        ;
    }

    void operator()(Args&&... args)
    {
        mCallable(std::forward(args)...);
    }
};

有了这个,我决定构建其他包装器,但我认为键入相同的代码片段并更改callable_t的using声明中的调用约定比需要更多的工作.所以我想找到一种方法来构建大约4种可调用类型的变体(对于每个调用约定),但是找不到一种方法.

到目前为止,我已经尝试使用枚举作为非类型模板参数,如下所示:

template 
class Function
{
    // ...
};

但我不知道如何迭代Call对象的类型并建立所需的类型(我尝试使用std :: is_same/std :: enable_if但这是一个死胡同).我还尝试使用这样的代码模板专业化:

struct StdcallT { ; };
struct CdeclT { ; };
struct FastcallT { ; };

template 
struct BaseT { };

template <> struct BaseT { using CallableT = void(__stdcall*)(); };
template <> struct BaseT { using CallableT = void(__cdecl*)(); };
template <> struct BaseT { using CallableT = void(__fastcall*)(); };

template 
class Function
{
    using CallableT = typename BaseT::CallableT;
};

但我没有考虑其余的参数(返回类型+参数),所以这也不行.

那么无论如何都有什么想法我能做什么?我正在考虑的一种方法是切换非类型参数并调用正确的参数,如下所示:

template 
class Function
{
    void operator()(ArgsT&&... args)
    {
        switch(Call)
        {
            case CallingConvention::Cdecl:
                // Call a __cdecl version
                break;
            case CallingConvention::Stdcall:
                // Call an __stdcall version
                break;
            // And so on...
        }
    }
};

尽管这看起来像一个工作的解决方案,我想知道是否有一些我没想到的好的替代方案.

有任何想法吗?

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有