0

I was wondering if someone could help me with this issue. I have been reading that the are some problems with the use of the std::make_pair in VS2010 because it is overloaded, and I have found some workarounds that would work, however, I just can not find a way to make it work here for me.

Here is a part of the code so you can take a look:

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
    )
);

The problem is here (the rest of the code is just to give an idea):

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
    )
);

I tried to do a cast (as I had read in other thread) but it did not work... this is what I had tried:

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
    )
);

I hope anyone can help me with this one... I have been stuck for a long time trying to compile this project...

By the way, it throws me a lot of error in the boost::bind (more than a hundred)... and taking out the boost::bind, it gives me errors about not knowing which overload of std::make_pair to use,

Regards, and thanks in advance!

4

2 回答 2

1

Dave S 是对的:这里使用 lambda 或仿函数会好得多。您遇到的问题make_pair可能是由于C++11 的重大变化make_pair现在有 typeT&&和的参数U&&,以实现对类型的完美转发。

你这样使用make_pair

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

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

简而言之:不要尝试使用make_pair或其他带有显式模板参数列表的完美转发函数;它们并非设计为以这种方式使用。

于 2012-05-22T22:38:06.263 回答
0

首先,我会注意常量,因为您正在获取引用的地址,但希望这对是指向非常量树::分支的指针。

如果您有 lambda,我会执行以下操作。

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)
);
于 2012-05-22T22:11:10.100 回答