在VS2010中使用boost :: bind的std :: make_pair错误

时间:2012-05-22 20:57:39

标签: c++ visual-c++ boost visual-c++-2010 boost-bind

我想知道是否有人可以帮我解决这个问题。我一直在阅读在VS2010中使用std :: make_pair是一些问题,因为它已经过载,我找到了一些可行的解决方法,但是,我找不到一种方法让它在这里工作我

以下是代码的一部分,您可以查看:

namespace tree {
    #define container std::vector
    typedef container<IConnType const*> node_data;

///tree node's brief
    struct tree_node
    {
        STD_STRING  name;
        node_data   types;
    };

    struct branch;
    typedef container<branch>           sub_tree;

///branch's brief
    struct branch
    {
        tree_node   node;
        sub_tree    tree;
    };
}



template<typename T>
///address of's brief
struct address_of
{
    T* operator()(T& x) const
    {
        return &x;
    }

    T const* operator()(T const& x) const
    {
        return &x;
    }
};



typedef std::pair<tree::branch*,HTREEITEM> step_info;
std::vector<step_info> steps;

/// after we fill steps ///

HTREEITEM new_item = m_conntree.InsertItem(&tvi); // m_conntree is a CTreeCtrl; tvi is a TVINSERTSTRUCT


std::transform(step.first->tree.begin()
    , step.first->tree.end()
    , std::back_inserter(steps)
    , boost::bind(&std::make_pair<tree::branch*,HTREEITEM>
        , boost::bind<tree::branch*>(address_of<tree::branch>()
            , _1
        )
    , new_item
    )
);

问题出在这里(其余代码只是为了提出一个想法):

std::transform(step.first->tree.begin()
    , step.first->tree.end()
    , std::back_inserter(steps)
    , boost::bind(&std::make_pair<tree::branch*,HTREEITEM>
        , boost::bind<tree::branch*>(address_of<tree::branch>()
            , _1
        )
    , new_item
    )
);

我试图做一个演员(正如我在其他帖子中读过的那样)但它没有用......这就是我曾经尝试过的:

typedef std::pair<tree::branch*,HTREEITEM> (*MakePairType)(tree::branch*,HTREEITEM);

std::transform(step.first->tree.begin()
    , step.first->tree.end()
    , std::back_inserter(steps)
    , boost::bind((MakePairType)&std::make_pair<tree::branch*,HTREEITEM>
        , boost::bind<tree::branch*>(address_of<tree::branch>()
            , _1
        )
    , new_item
    )
);

我希望有人能帮助我解决这个问题......我已经被困了很长时间试图编译这个项目......

顺便说一句,它在boost :: bind(超过一百)中抛出了很多错误......并取出了boost :: bind,它给出了我不知道std的哪个重载错误: :make_pair使用,

问候,并提前感谢!

2 个答案:

答案 0 :(得分:1)

Dave S是对的:这里的lambda或者functor会好得多。您make_pair遇到的问题可能是a breaking change in C++11造成的。 make_pair现在具有T&&U&&类型的参数,可以完美转发配对类型。

你正在使用make_pair

std::make_pair<tree::branch*,HTREEITEM>

由于您已明确命名模板类型参数,因此参数类型将选为tree::branch*&&HTREEITEM&&。此函数不能接受左值参数。

简而言之:不要尝试将make_pair或其他完美转发函数与显式模板参数列表一起使用;它们不是为那种方式设计的。

答案 1 :(得分:0)

首先,我会小心constness,因为你正在获取引用的地址,但是期望该对是一个指向非常量tree :: branch的指针。

如果你有lambdas,我会做以下事。

std::transform(step.first->tree.begin()
    , step.first->tree.end()
    , std::back_inserter(steps)
    [&](tree::branch& branch) { return std::make_pair(&branch, new_item); }
);

如果你没有lambda支持,如果你试图自己编写仿函数,至少在短期内,可能会更清楚,以获得更清晰的错误。 boost::bind功能强大,但是当它失败时,错误消息有时会隐藏一些基本的东西。

struct make_step_info
{ 
   HTREEITEM new_item;

   make_step_info(HTREEITEM new_item): new_item(new_item)  {};

   std::pair<tree::branch*,HTREEITEM> operator()(tree::branch& branch) const
   {
      return std::make_pair(&branch, new_item);
   }
}

/* And use it here */
std::transform(step.first->tree.begin()
     , step.first->tree.end()
     , std::ba_ck_inserter(steps)
     make_step_info(new_item)
);