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

2.3k views Asked by At

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.

2

There are 2 answers

0
Dietmar Kühl On BEST ANSWER

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.

0
Kerrek SB On

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.