【问题标题】:c++ void* to parameter to a functionc++ void* 为函数提供参数
【发布时间】:2012-02-03 08:43:19
【问题描述】:

我在某个库中有这个功能:

class myConsole
{
    void addCommand( std::string command, void* fn );
    ...
}

在我的课堂上我有这个功能:

void myApp::TestFn( const std::vector<std::string> & args )
{
    // do something
}

在同一个班级我称之为:

void myApp::initApp( )
{
    myConsole::getSingleton( ).addCommand( "FirstTest", &myApp::TestFn );
}

但这给了我这个错误:

错误 c2664 无法将参数 2 从 'void(__thiscall myApp::*)(const std::vector<_ty>&)' 到 'void *'

我该如何解决这个问题?

提前致谢!

【问题讨论】:

  • 之后你打算如何使用void* fn
  • myApp::TestFn 是否访问myApp 的任何成员变量?
  • 你有控制myConsole的声明,还是别人的库?要么将其更改为接受指向对象的指针和指向成员函数的指针,要么是仿函数,要么是指向全局函数的指针和指向任意“状态”的指针(可以只调用类指针的成员函数)作为州通过)。如果不是,您将必须 (a) 接受如果它假定函数指针和 void* 是可互换的(这适用于许多计算机/操作系统,但不是全部)并且 (b) 接受您需要一个命令函数将始终使用的全局对象。

标签: c++ visual-c++ function-pointers void-pointers


【解决方案1】:

You can't 解决这个问题。您不能可靠地将函数指针转换为 void * 并返回。

(我建议你重新设计程序并远离void*;C++ 中没有真正需要它。)

【讨论】:

    【解决方案2】:

    这里的问题是你试图传递一个类方法,因为它是一个void * 指针。这是做不到的。

    正确的做法是使用void addCommand (std::string, void *) 方法的模板。类似的东西

    class myConsole {
        template <typename T>
        void addCommand( std::string command, T f);
    };
    
    struct Callback {
        myApp &app;
        Callback (myApp &a) : app(a) {
        }
        void operator() (const std::vector<std::string> &args) {
            app.TestFn(args);
        }
    };
    
    void myApp::initApp( )
    {
        myConsole::getSingleton( ).addCommand( "FirstTest", Callback(*this) );
    }
    

    这为您提供了 C++ 中的回调原理,但我认为您需要比此解决方案更灵活的东西,因为您实际上希望自动选择将由回调执行的命令(在本例中为 TestFn)。

    【讨论】:

      【解决方案3】:

      您应该避免使用void*,尤其是在尝试使用函数指针时。我将假设您只查看myApp 类中的成员函数指针,并且您只对以const std::vector&lt;std::string&gt; &amp;args 作为参数的成员函数指针感兴趣。这个 typedef 会创建合适的类型并命名为MemFunType

      typedef void (myApp :: * MemFunType) (const std::vector<std::string> &);
      

      这是一个完整的示例(在ideone 上),其中有两个您可能感兴趣的不同成员函数,TestFnTestFnBackwards。这个例子可能不是很有用,但它给出了一些成员函数指针的例子。

      #include<iostream>
      #include<vector>
      using namespace std;
      
      struct myApp;
      
      struct myConsole
      {
              typedef void (myApp :: * MemFunType) (const std::vector<std::string> &);
                  void addCommand( std::string command, MemFunType fn );
      };
      
      struct myApp {
              void TestFn( const std::vector<std::string> & args ) {
                      cout << " TestFn" << endl;
                      for(std :: vector<std::string> :: const_iterator i = args.begin(); i!=args.end(); i++) {
                              cout << *i << endl;
                      }
              }
              void TestFnBackwards( const std::vector<std::string> & args ) {
                      cout << " TestFnBackwards" << endl;
                      for(std :: vector<std::string> :: const_reverse_iterator i = args.rbegin(); i!=args.rend(); i++) {
                              cout << *i << endl;
                      }
              }
              static myApp & getSingleton();
      } ma;
      myApp& myApp :: getSingleton() {
              return ma;
      }
      
      void myConsole :: addCommand( std::string , MemFunType fn ) {
              vector<string> words;
              words.push_back("hello");
              words.push_back("world");
              myApp &ma = myApp :: getSingleton();
              (ma.*fn)(words); // execute the member on the singleton object, using the words as the argument.
      }
      
      int main() {
              myConsole m;
              m.addCommand( "FirstTest", &myApp::TestFn );
              m.addCommand( "FirstTest", &myApp::TestFnBackwards );
      }
      

      【讨论】:

      • 谢谢,但在这种情况下,我需要在控制台类中链接 myApp 类的引用(如果我有多个类调用 myConsole 很难......)
      • @ghiboz,我认为您需要大量编辑您的问题。我建议您停止编写代码并尝试清楚地传达您的目标。您是否真的希望addCommand(用简单的英语)接受三条信息:(1)指向myAppinstance 的引用/指针,(2)要在该 myApp 对象上调用的成员函数,(3) 命令字符串?
      猜你喜欢
      • 2018-05-15
      • 2017-07-13
      • 1970-01-01
      • 2014-04-04
      • 2014-07-11
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      相关资源
      最近更新 更多