首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost::线程()不接受参数

Boost::线程()不接受参数
EN

Stack Overflow用户
提问于 2014-12-09 20:19:36
回答 3查看 1.1K关注 0票数 3

IDE向我抱怨线程不包含我传递给它的参数数。这是因为他们太多了我相信..。

当我为线程使用标准库时,我也遇到了同样的问题,但是对于兼容性问题,我需要使用Boost::线程。这里链接到我之前的问题,有人解释说这个问题是由可验证模板引起的。

这确实是一个问题,然而,在切换到boost线程之后,这个错误就会返回,而更改可验证的最大值并不能修复它。

这是我的线程声明

boost::thread db(writeToDB, coordString, time, std::to_string(id), imageName, azimuth, att_pitch, att_roll, yaw, cam_pitch, cam_roll);

编辑:

下面是我如何尝试bind函数:

boost::thread db(boost::bind(::writeToDB, coordString, time, std::to_string(id), imageName, azimuth, att_pitch, att_roll, yaw, cam_pitch, cam_roll));

当前的IDE是Visual 2013,但是它需要与Visual 2008兼容

这里也是我所收到的实际错误:

错误:

Error 6 error C2661: 'boost::thread::thread' : no overloaded function takes 11 arguments c:\users\hewittjc\desktop\final project\project1\clientexample.cpp 174 1 Project1

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-09 21:16:12

Boost.Thread (在内部利用Boost.Bind来绑定参数)只支持一些固定数量的参数(文档):

带参数的线程构造器 模板线程( F,A1 a1,A2 a2,.); 先决条件: F和每个An必须是可复制的或可移动的。 效果: 就像thread(boost::bind(f,a1,a2,...))。因此,f和每个an被复制到内部存储中,以便由新线程进行访问。 邮政条件: *this指的是新创建的执行线程。 抛出: 如果发生错误,则为boost::thread_resource_error。 错误条件: resource_unavailable_try_again:系统缺乏创建其他线程所需的资源,或者系统对进程中线程数量的限制将被超越。 注意: 目前,除了函数a1 f**.**之外,还可以指定最多9个附加参数( to a9 )。

显然,这意味着传递 11 参数(就像您所做的那样)必须导致您看到的错误:“没有重载的函数接受11个参数”。

不幸的是,没有一种简单的方法来延长限制。可能的解决办法是:

  • 减少参数的总数量(你只比限制多了一个)
  • 使用其他库来绑定参数,如Boost.Phoenix
  • 将参数包装在类类型变量(或至少其中一些变量)中
  • 切换到完全支持各种模板的std::thread编译器上的C++11编译器。
票数 2
EN

Stack Overflow用户

发布于 2014-12-09 21:25:38

来自Boost.Thread文档

注意: 目前,除了函数f之外,还可以指定最多9个附加参数a1到a9。

Boost.Bind也有同样的限制。您可以尝试一下MSVC 2008所拥有的std::tr1::bind,但我怀疑它在那里会很相似--您确实需要各种模板才能正确地制作bind,而MSVC 2008没有它们。我认为只有Boost.Spirit人才是真正疯狂到能够通过预处理器元编程实现这一目标的人,他们把它变成了Boost.Phoenix。在这里,您可以通过预处理器指定一个上限,如下所示:

代码语言:javascript
复制
// Set this before headers are included.
// ...best set it projectwide. I don't know if funny stuff happens if Phoenix is
// used with different limits in different translation units.
//
// Also, please read the stuff below.
//
#define BOOST_PROTO_MAX_ARITY 20
#define BOOST_PROTO_MAX_LOGICAL_ARITY 20

#include <boost/phoenix/bind.hpp>
#include <boost/thread.hpp>

#include <iostream>

void foo(int x0, int x1, int x2, int x3, int x4,
         int x5, int x6, int x7, int x8, int x9,
         int x10)
{
  std::cout << x0 << x1 << x2 << x3 << x4
            << x5 << x6 << x7 << x8 << x9
            << x10 << "\n";
}

int main() {
  boost::thread th(boost::phoenix::bind(&foo, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
  th.join();
}

现在,这个特性相当粗糙。我觉得控制这一点的预处理宏已经被看作是一种后遗症。在Boost.Phoenix文档中,它说您应该能够通过BOOST_PHOENIX_LIMIT来控制它,这在很久以前是正确的,但是在创建Boost.Proto主干网期间,它似乎已经改变了,并且文档没有被更新。它也是粗糙的边缘在其他方面。例如,它只适用于我的值为20 (如果你真的很耐心的话,我想还有30,40等等) --从11到19之间的任何东西都会产生巨大的编译器错误--编译需要很长时间,因为它突然有1048576个函数模板重载要处理。

因此,这是可行的(对我来说,使用Boost 1.55.0),但它并不是真正需要依赖的东西。相反,我建议您将参数组合在结构中,这样您就可以将不到10个参数传递给writeDB,或者编写您自己的函子(带有and...nevermind),比如

代码语言:javascript
复制
// "..." to mean the rest of the arguments
class writeDBFunctor {
public:
  writeDBFunctor(std::string coordString, ...) : coordString(cordString), ... { }

  void operator()() {
    writeDB(coordString, ...);
  }

private:
  std::string coordString;
  // ...and the other arguments saved here
}

然后把它交给boost::thread

票数 0
EN

Stack Overflow用户

发布于 2018-05-04 17:11:07

如果你想要使用boost线程的话,你只需要创建一个临时的“物品盒”。简单的例子:我想推动::线程跟随..。

代码语言:javascript
复制
/// d2dclass
static void draw_tree(ID2D1RenderTarget* d2rt,
                      ID2D1Brush*        brush,
                      float X, float Y, float len,
                      int level,
                      float angle = -DirectX::XM_PIDIV2,
                      float dispersion = DirectX::XM_PIDIV2,
                      int split = 2, float shrink = 0.5f,
                      float sw = 1.0f,
                      ID2D1StrokeStyle* ss = NULL,
                      HANDLE interrupt = NULL);

它是一个简单的递归D2D1树绘制函数。

定义参数数据持有者。

代码语言:javascript
复制
struct dth_para {
    ID2D1RenderTarget* _d2rt;
    ID2D1Brush*      _brush;
    float _X;
    float _Y;
    float _len;
    int _level;
    float _angle;
    float _dispersion;
    int _split;
    float _shrink;
    float _sw;
    ID2D1StrokeStyle* _ss;
    HANDLE _interrupt;
};

使用boost定义一个简单的线程调用版本::线程&(引用)使用模板。(你可能想同时做几个)和一个急进版本。实际上,这部分我不确定它是否需要。每个线程都会创建独立的工作区,但不会造成任何伤害。在第一个函数中声明一个静态变量,这样它就不会从堆栈中消失。

代码语言:javascript
复制
/// class d2dclass

template<size_t num_tree>
static void draw_tree_thread(boost::thread& tth,
                             ID2D1RenderTarget* d2rt,
                             ID2D1Brush*         brush,
                             float X, float Y, float len,
                             int level,
                             float angle = -DirectX::XM_PIDIV2,
                             float dispersion = DirectX::XM_PIDIV2,
                             int split = 2, float shrink = 0.5f,
                             float sw = 1.0f,
                             ID2D1StrokeStyle* ss = NULL,
                             HANDLE interrupt = NULL) {
    static dth_para tree_para;
    tree_para._d2rt = d2rt;
    tree_para._brush = brush;
    tree_para._X = X;
    tree_para._Y = Y;
    tree_para._len = len;
    tree_para._level = level;
    tree_para._angle = angle;
    tree_para._dispersion = dispersion;
    tree_para._split = split;
    tree_para._shrink = shrink;
    tree_para._sw = sw;
    tree_para._ss = ss;
    tree_para._interrupt = interrupt;
    tth = boost::thread(boost::bind(&draw_tree_thread_mpl, boost::ref(tree_para)));
}

static void draw_tree_thread_mpl(dth_para& params) {
    draw_tree(params._d2rt,
              params._brush,
              params._X,
              params._Y,
              params._len,
              params._level,
              params._angle,
              params._dispersion,
              params._split,
              params._shrink,
              params._sw,
              params._ss,
              params._interrupt);
}

调用appropiate函数。

代码语言:javascript
复制
boost::thread sth;
d2dclass::draw_tree_thread<0>(sth,
                              d3d->getd2rendertarget(),
                              pRadialGradientBrush0,
                              d3d->get_ww() / 2,
                              d3d->get_wh() - TREE_LEN,
                              TREE_LEN,
                              LEVELS,
                              -DirectX::XM_PIDIV2,
                              DISPERSION,
                              2,
                              OPA_SHRINK,
                              -6.0f,
                              NULL,
                              interrupt);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27388068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档