Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I initialize boost::any with a reference to an object?

I want to store a reference to an object in a boost::any object. How do I initialize the boost::any object? I tried std::ref(), but boost::any gets initialized with std::reference_wrapper<>. For example, the following

#include <boost/any.hpp>
#include <cxxabi.h>
#include <iostream>

int main(void)
{
  int s;
  int i = 0;
  boost::any x(std::ref(i));
  std::cout << abi::__cxa_demangle(x.type().name(), 0, 0, &s) << "\n";
  return 0;
}

prints

std::reference_wrapper<int>

I want the boost::any to contain int& instead.

like image 951
keveman Avatar asked Jan 14 '12 20:01

keveman


2 Answers

The boost::any class doesn't have an interface allowing something like this: you would need to specify the type of the reference with the constructor. I don't think that you can explicitly specify the type of templated constructor because I don't see any place you could stick it. Even if you can explicitly specify the template parameter, it wouldn't work in C++2003 bcause there is no reference collapsing available and the parameter is declared as taking a T const&: you'd be trying to create a T& const& which won't fly. I think your best option is to either use std::reference_wrapper<T> if you insist on something looking remotely reference like or just to use T*.

That said, it would be generally possible to have a templatized static factor method of a type similar to boost::any which would be used to explicitly specify the template argument. However, since boost::any is deliberately designed to deal with value types this isn't done. I'm a bit dubious whether it should be done as well: using a pointer is perfectly good alternative. If you really need a reference type you'll probably have to implement it yourself.

like image 73
Dietmar Kühl Avatar answered Oct 03 '22 05:10

Dietmar Kühl


The behaviour is correct, expected and appropriate. std::ref is a helper function that creates an object of type std::reference_wrapper<T>, and the reference wrapper is a class with value semantics that holds a reference -- that's exactly the sort of thing you want to put into a container if you want the container to track outside references.

So just go with the solution you have.

If you will, you cannot have a container of direct, naked references, much like you cannot have an array of references. The wrapper is designed precisely to accommodate such needs.

like image 42
Kerrek SB Avatar answered Oct 03 '22 04:10

Kerrek SB