如何在C++(或C)中将Virtually Anything传递给函数?

App*_*ker 4 c c++ pointers function

我需要传递类似指针的东西,它将任何东西作为函数参数.你知道,没有任何预定义类型或类型的东西可以采取这样的事情:

 void MyFunc( *pointer ); 
Run Code Online (Sandbox Code Playgroud)

然后使用它像:

char * x = "YAY!";
MyFunc(x);

int y = 10;
MyFunc(&y);

MyObj *b = new MyObj();
MyFunc(b);
Run Code Online (Sandbox Code Playgroud)

而且我不想使用模板,因为我在我的项目中主要使用C语言.除了函数宏之外,还有什么可以在这里使用吗?

Cor*_*son 11

在C++中,Boost.Any将允许您以类型安全的方式执行此操作:

void func(boost::any const &x)
{
    // any_cast a reference and it
    // will throw if x is not an int.
    int i = any_cast<int>(x);

    // any_cast a pointer and it will
    // return a null pointer if x is not an int.
    int const *p = any_cast<int>(&x);
}

// pass in whatever you want.
func(123);
func("123");
Run Code Online (Sandbox Code Playgroud)

在C中,您将使用void指针:

void func(void const *x)
{
    // it's up to you to ensure x points to an int.  if
    // it's not, it might crash or it might silently appear
    // to work. nothing is checked for you!
    int i = *(int const*)x;
}

// pass in whatever you want.

int i = 123;
func(&i);

func("123");
Run Code Online (Sandbox Code Playgroud)

你似乎对它不利,但无论如何我都会推荐它:如果你正在使用C++,请接受它.不要害怕模板.像Boost.Any和void指针这样的东西在C++中占有一席之地,但它非常小.

更新:

好吧,我正在制作一个小信号 - 插槽 - 连接库,用于我的gui工具包.这样我就可以摆脱丑陋的WNDPROC.我需要这些连接指针.

如果您需要多目标信号,Boost.Signals已经提供了完整且经过测试的信号/插槽实现.您可以使用Boost.Bind(或者std::bind,如果您有一个C++ 0x编译器)来连接成员函数:

struct button
{
    boost::signal<void(button&)> on_click;
}

struct my_window
{
    button b;

    my_window()
    {
        b.on_click.connect(std::bind(&my_window::handle_click,
                                     this, std::placeholders::_1));
    }

    void handle_click(button &b)
    {
    }

    void simulate_click()
    {
        b.on_click(b);
    }
};
Run Code Online (Sandbox Code Playgroud)

如果你只想要一个简单的回调,Boost.Function(或者std::function如果你有一个C++ 0x编译器)将运行良好:

struct button
{
    std::function<void(button&)> on_click;
}

struct my_window
{
    button b;

    my_window()
    {
        b.on_click = std::bind(&my_window::handle_click,
                               this, std::placeholders::_1);
    }

    void handle_click(button &b)
    {
    }

    void simulate_click()
    {
        b.on_click(b);
    }
};
Run Code Online (Sandbox Code Playgroud)


Ben*_*igt 7

您可以使用带a的函数void*,但必须注意与以下函数不兼容的指针类型void*:

虽然这些指针不兼容void*(即使在某些编译器上使用了转换),但它们本身就是数据.所以你可以传递指针指针:

void MyFunc(void*);

void (*pfn)(void*) = &MyFunc;
MyFunc(&pfn); // ok

struct A { int x; };
int A::*px = &A::x;
MyFunc(&px); // ok
Run Code Online (Sandbox Code Playgroud)