你能使用boost :: reference_wrapper在STL容器中存储引用吗?

时间:2012-04-22 20:51:44

标签: c++ boost

我试图这样做:保留两个字符串向量,其中一个向量存储值,第二个存储相同值的引用。我认为使用boost::reference_wrapper可以做到这一点,但似乎不会。我的平台是Visual C ++ 2008。

std::vector<std::string> str_vec;
str_vec.push_back("abc");
str_vec.push_back("cde");
str_vec.push_back("fgh");

std::vector<boost::reference_wrapper<std::string> > str_view;
for(std::vector<std::string>::iterator it = str_vec.begin(); it != str_vec.end(); ++it)
{
  str_view.push_back(*it);
}

这是错误:

  

错误C2664:'std :: vector&lt; _Ty&gt; :: push_back':无法从std :: basic_string转换参数1&lt; _Elem,_Traits,_Ax&gt;' 'const boost :: reference

我可以使用boost::shared_ptr,但我认为参考更好地表达了我的意图。这段代码可能在使用std::reference_wrapper的C ++ 11中工作,但现在我无法使用。

1 个答案:

答案 0 :(得分:2)

是的,它可以。文档声明它是CopyConstructibleAssignable,它们是容器模板参数的必需概念。但您需要使用boost::refboost::cref来创建reference_wrapper类型的对象。没有隐式转换,这就是您的代码不起作用的原因。

请注意,std::reference_wrapperboost::reference_wrapper之间的细微差别是只有std版本适用于仿函数。

示例:

std::vector<std::string> str_vec;
str_vec.push_back("abc");
str_vec.push_back("cde");
str_vec.push_back("fgh");

std::vector<boost::reference_wrapper<std::string> > str_view;
std::transform(begin(str_vec), end(str_vec),
               std::back_inserter(str_view), boost::ref<std::string>);

如果您不喜欢并希望从原始值进行隐式转换,则可能需要使用:

template<typename T>
class my_ref_wrap : public boost::reference_wrapper<T> {
public:
  my_ref_wrap(T& t) : boost::reference_wrapper<T>(t) {}
};

std::vector<my_ref_wrap<std::string> > str_view;
std::copy(begin(str_vec), begin(str_vec),
          std::back_inserter(str_view));

虽然我不这样做。