在C ++中动态给定函数参数 [英] Giving a function argument dynamically in C++

查看:74
本文介绍了在C ++中动态给定函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码,根据以下for循环创建线程,pthread中的第3个参数采用void *()(void ),并给它一个字符串arg。问题在于每个线程都有自己的方法,即线程0拥有其方法thread0()。我希望能够基于for循环的t设置方法而不会出现以下错误:

I have the following code where I create threads based on the for loop below, the 3rd argument in pthread takes a void* ()(void) and I am giving it a string arg. The problem is that every thread has it's own method i.e thread 0 has its method thread0(). I want to be able to set the method based on the t of the for loop without getting the following error:


main2.cpp:40:51: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
 err = pthread_create(&threads[t], &attr,method, &t);




for(t = 0; t <5; t++){;
    printf("Creating thread %d\n",t);
    std::string method = "thread"+t;
    err = pthread_create(&threads[t], &attr,method, &t);
    if(err != 0) exit(-1);
}


推荐答案

错误消息非常清楚关于函数指针,您不能将c ++符号转换为字符串,反之亦然。

The error message is pretty clear about the function pointer, that you can't translate c++ symbols to strings or vice versa.

这是 pthread_create()文档中给出的c $ c>:

Here's the signature of pthread_create() as given in the documentation:



简介



int pthread_create (pthread_t * thread,const pthread_attr_t * attr,
void * (* start_routine)(void *),void * arg);


您可以执行以下操作:

typedef void* (*start_routine_t)(void*);

void* foo_0(void*) { return nullptr; }
void* foo_1(void*) { return nullptr; }    
void* foo_2(void*) { return nullptr; }
void* foo_3(void*) { return nullptr; }
void* foo_4(void*) { return nullptr; }

constexpr std::map<std::string,start_routine_t> thread_funcs {
    { "thread_0" , foo_0 } ,
    { "thread_1" , foo_1 } ,
    { "thread_2" , foo_2 } ,
    { "thread_3" , foo_3 } ,
    { "thread_4" , foo_4 } ,
};

pthread_t threads[5];


// ....

for(t = 0; t <5; t++){;
    printf("Creating thread %d\n",t);
    std::ostringstream method;
    method << "thread_" <<t;
    err = pthread_create(&threads[t], &attr,method, &thread_funcs[method.str()],nullptr);
    if(err != 0) exit(-1);
}

或更简单的方法是完全不使用字符串:

Or the more straightforward way without using strings at all:

start_routine_t thread_funcs[5] = { foo_0, foo_1, foo_2, foo_3, foo_4 }; 
pthread_t threads[5];

// ...

for(t = 0; t <5; t++){
    printf("Creating thread %d\n",t);
    err = pthread_create(&threads[t], &attr,method, thread_funcs[t], nullptr);
    if(err != 0) exit(-1);
}






正如您所要求的c ++-11 设施:


  1. 直接使用 std :: thread 代替pthread-API所有。如果目标环境正确支持pthread,通常可以使用 std :: thread ABI。

  2. 使用lambda函数来

  1. Use std::thread instead of the pthread-API directly at all. If your target environment supports pthreads properly, you usually can use the std::thread ABI.
  2. Use lambda functions to refer to specific routines on the fly:

std::vector<std::thread> threads(5);
for(t = 0; t <5; t++){
   printf("Creating thread %d\n",t);
   auto thread_func = [t]() {
       switch(t) {
       case 0: foo_0(); break;
       case 1: foo_1(); break;
       case 2: foo_2(); break;
       case 3: foo_3(); break;
       case 4: foo_4(); break;
       }               
   };
   threads[t] = std::thread(thread_func);
}

上面的代码示例可能不是最好的(效率最高),但是演示如何动态映射函数调用。

The above code example probably isn't the best (most efficient), but demonstrates how to map function calls on the fly.

这篇关于在C ++中动态给定函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆