boost :: any / any_ostreamable

时间:2018-11-04 20:39:51

标签: c++

以下代码显示666666,尽管我想要12345。

怎么了?如何解决?

#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/any_cast.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/mpl/vector.hpp>
#include <vector>
#include <iostream>
using namespace boost::type_erasure;
using namespace std;

typedef any<boost::mpl::vector<boost::type_erasure::typeid_<>, ostreamable<>>, const _self&> any_ostreamable;
typedef std::vector<any_ostreamable> any_ostreamable_vector;

int main (int argc, char** argv) {
  any_ostreamable_vector args;
  for (int i=1; i<=5; i++)
    args.emplace_back(i);
  for (auto& arg: args)
    cout << arg;
}    

起初,我认为这是因为 i 是通过any_ostreamable中的引用捕获的,因此是同一引用的5倍,而值6是 i 退出循环时具有。

因此,我尝试用args.emplace_back(i args.emplace_back(i);替换+0);,传递一个rvalue,强制构造一个新的int。 丢失!在那种情况下,我得到55555。通过使用i + 1,我得到66666,i + 2 77777,等等。

我说args.emplace_back(int(i));也会得到66666。

我什至尝试过args.emplace_back(i*i);,但是我又获得了2525252525而不是1491625。

如果在迭代之后观察到迭代向量包含的内容,则会得到类似于1、22、333、4444、55555的信息。因此,即使我写i+0int(i)i*i ,any_ostreamable似乎捕获了相同引用的5倍。

如果我使用push_back而不是emplace_back,则上述所有内容都将得到相同的结果。 如果我用任何n!= 0来写i+n,也是如此。

如果我使用double而不是ints,甚至使用精心构造的str :: string,也会发生同样的事情。

有人可以解释发生了什么事吗?

如何获得所需的输出?如果可能的话,不更改any_ostreamable typedef。那是我唯一没有尝试过的事情,因为我不确定在不改变真实程序其他地方的预期副作用的情况下如何/可以做些什么。

编译器:具有G ++ 5.3.0的MinGW32,可在C ++ 14中进行编译。

谢谢您的回答。

1 个答案:

答案 0 :(得分:0)

您悬空了对不再存在的对象的引用。当您遵循悬空的引用时,结果是未定义的行为。

基于引用的类型擦除作为函数API是合理的;否则,这是一个糟糕的计划。