当转换函数按值返回时,boost::adaptors::transformed的意外行为

Unexpected behavior of boost::adaptors::transformed when the transformation function returns by value

提问人:koral 提问时间:8/22/2019 最后编辑:koral 更新时间:8/24/2019 访问量:116

问:

考虑以下一段 C++11 代码,这是我能想到的最小的复制器:

#include <iostream>
#include <boost/range/adaptor/transformed.hpp>

std::vector<uint32_t> myTransform(const std::vector<uint32_t>& iVector) {
  return iVector;
}

int main() {
  const std::vector<std::vector<uint32_t>> theInput{{1, 2}};
  const auto myRange = theInput | boost::adaptors::transformed(myTransform);

  for (auto it = boost::begin(myRange); it != boost::end(myRange); ++it) {
    for (auto it2 = boost::begin(*it); it2 != boost::end(*it); ++it2) {
      std::cout << *it2 << std::endl;
    }
  }
}

我希望它打印以下输出:

1
2

...但它会打印(参见 http://cpp.sh/8yivt):

0
0

但是,如果我更改为返回如下引用:myTransform

const std::vector<uint32_t>& myTransform(const std::vector<uint32_t>& iVector) {
  return iVector;
}

...然后我得到预期的输出(参见 http://cpp.sh/5brvl)。

我无法从 Boost.Range 文档中找到对此行为的任何解释。我的代码不正确吗?我的期望不正确吗?这是 Boost.Range 中的错误/已知限制吗?

这个问题的目的首先是要理解为什么它会以一种意想不到的方式表现出来,并且只是顺便找到解决方案。

C++ C++11 范围 升压适配器

评论

2赞 Justin 8/22/2019
尝试 和 ,或尝试基于 for 循环的范围: 。我怀疑它按值返回一个向量,该向量在调用 后立即被销毁,这意味着悬空。auto vec = *itfor (auto it2 = boost::begin(vec); it2 != boost::end(vec); ++it2) { ... }for (uint32_t x : *it) { ... }*itboost::beginit2
0赞 koral 8/22/2019
使用 打印预期的输出 (cf cpp.sh/5hw3t)。auto vec = *it1 2
0赞 koral 8/29/2019
我也怀疑被迅速销毁,问题的重点是要了解为什么,如果确实如此。*it
0赞 Justin 8/29/2019
查找“临时生存期”或“临时生存期”。简而言之,临时性只活到语句的末尾(通常是下一个)。对象在其生命周期结束时会自动销毁。因此,临时在初始化之后,但在实际发生任何迭代之前被销毁。;it2

答: 暂无答案