1

I'm trying to use Boost::Fusion to transform a list of function's parameter types into a fusion::list. Ultimately, I am trying to turn a list of variables into parameters that I can call a function with (http://stackoverflow.com/questions/11164914/generating-wrappings-for-c-functions).

I've gotten this to work for non-referenced variables. However, it fails to compile for non-referenced variables when I try to turn the function's parameter list (specifically on the fusion::to_list it complains it can't deref the iterator).

I've simplified the code down by a bit below:

struct identity {
  template<typename Sig> struct result;

  template <typename T>
  struct result<convert(T)> { typedef T type; };

  template <typename T>
  typename T operator ()(T) const { 
     return T();
  }
};

int main(int argc, char **argv) {
  typedef BOOST_TYPEOF(foo) params_type;
  auto seq = function_types::parameter_types<params_type>();
  auto transformed = fusion::transform(seq, identity());
  auto passedParams = fusion::as_list(transformed);
}

If foo is defined as:

int foo(int a) { return 5*a; }

it works fine, but it breaks on:

int foo(int &a) { return 5*a; }

For the purposes of my code, I don't actually need the references kept in the sequence, which I am assuming is the issue (also, searches I've done tend to point that as being the culprit). However, I'm not completely sure of how to strip the transformed function of these references before as_list is called.

I tried something along the lines of:

template <typename T>
struct result<convert(T)>: remove_reference<T> {};

template <typename T>
typename remove_reference<T>::type operator ()(remove_reference<T>::type) const { return typename remove_reference<T>::type(); }

but got the same compile errors.

Any ideas of how to fix this?

update

Here is the truncated compiler error I get (with clang++ --std=c++0x) for both cases given above:

/usr/local/include/boost/fusion/adapted/mpl/mpl_iterator.hpp:43:24: error: 
      reference to type 'int' requires an initializer
                return type();
                       ^
/usr/local/include/boost/fusion/iterator/deref.hpp:61:28: note: in instantiation
  of member function
  'boost::fusion::mpl_iterator<boost::mpl::v_iter<boost::function_types::parameter_types<void
  (int &), boost::add_reference<mpl_::arg<-1> > >, 0>
  >::deref<boost::fusion::mpl_iterator<boost::mpl::v_iter<boost::function_types::parameter_types<void
  (int &), boost::add_reference<mpl_::arg<-1> > >, 0> > >::call' requested
  here
    return deref_meta::call(i);

...

test4.cpp:65:22: note: in instantiation of function template specialization
  'boost::fusion::as_list<boost::fusion::transform_view<const
  boost::function_types::parameter_types<void (int &),
  boost::add_reference<mpl_::arg<-1> > >, convert, boost::fusion::void_> >'
  requested here
    auto passedParams = fusion::as_list(transformed);
Abe Schneider
  • 977
  • 1
  • 11
  • 23
  • If you get compilation errors, it would be a good idea to edit your question to include them. – Some programmer dude Jun 26 '12 at 05:27
  • Will do -- I avoided doing so because it's template error and therefore long and difficult to parse. Because of that I included (above) the final error the compiler gives (when calling as_list in deref_impl). – Abe Schneider Jun 26 '12 at 12:36
  • Ok, I added an abbreviated form of the error. I can include more if it helps, the trace runs through: defer.hpp -> defer_impl.hpp -> defer.hpp -> build_cons.hpp -> convert.hpp -> test4.cpp – Abe Schneider Jun 26 '12 at 14:48

1 Answers1

1

If your compiler is C++11 compatible, you might want to look into the `std::remove_reference function. Or at least try to find an implementation of it and use as reference for making your own.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I did try remove_reference (see above), but might not have applied it correctly. Can you give any example of applying it to a fusion view? – Abe Schneider Jun 26 '12 at 12:34