N
Noah Roberts
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/tuple/tuple.hpp>
template < int I >
struct placeholder {};
namespace {
placeholder<0> a1;
placeholder<1> a2;
placeholder<2> a3;
}
template < typename ARGS
, typename IDX >
IDX lookup(ARGS&, IDX idx) { return idx; }
template < typename ARGS
, int IDX >
typename boost::fusion::result_of::at<ARGS, boost::mpl::int_<IDX> >::type lookup(ARGS & args, placeholder<IDX>)
{
return boost::fusion::at_c<IDX>(args);
}
template < typename ARGS
, int IDX >
typename boost::tuples::element<IDX, ARGS>::type lookup(ARGS & args, placeholder<IDX>)
{
return boost::tuples::get<IDX>(args);
}
..... cpp ...
BOOST_AUTO_TEST_CASE(lookup_check)
{
boost::fusion::vector<int, char, std::string> args(42, 'c', "Hello");
//BOOST_CHECK(lookup(args, 13) == 13);
//BOOST_CHECK(lookup(args, a3) == "Hello");
boost::tuple<int, char, std::string> args2(19, 'q', "World");
BOOST_CHECK(lookup(args2, 88) == 88);
BOOST_CHECK(lookup(args2, a2) == 'q');
}
The tuple version of course does not work with the fusion version. The fusion version results in a bunch of errors about incomplete types and such. I would expect this to be filtered out by SFINAE and use only the tuple version, but that is not happening. Why?
Here be the error output:
In file included from /usr/include/boost/fusion/include/at.hpp:10:0,
from /home/nroberts/workspace/static_binder/test/../include/bind.hpp:5,
from /home/nroberts/workspace/static_binder/test/bind_test..cpp:5:
/usr/include/boost/fusion/sequence/intrinsic/at.hpp: In instantiation of ‘boost::fusion::result_of::at<boost::tuples::tuple<int, char, std::basic_string<char> >, mpl_::int_<1> >’:
/home/nroberts/workspace/static_binder/test/bind_test.cpp:18:2: instantiated from here
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:56:16: error: invalid use of incomplete type ‘struct boost::fusion::extension::at_impl<boost::fusion::non_fusion_tag>::apply<boost::tuples::tuple<int, char, std::basic_string<char> >, mpl_::int_<1> >’
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:30:20: error: declaration of ‘struct boost::fusion::extension::at_impl<boost::fusion::non_fusion_tag>::apply<boost::tuples::tuple<int, char, std::basic_string<char> >, mpl_::int_<1> >’
I know why it might not if it had made it past the signature of the function but it has not in this case. I don't understand why it isn't just aborting this function as a non-viable overload.
Thanks.
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/tuple/tuple.hpp>
template < int I >
struct placeholder {};
namespace {
placeholder<0> a1;
placeholder<1> a2;
placeholder<2> a3;
}
template < typename ARGS
, typename IDX >
IDX lookup(ARGS&, IDX idx) { return idx; }
template < typename ARGS
, int IDX >
typename boost::fusion::result_of::at<ARGS, boost::mpl::int_<IDX> >::type lookup(ARGS & args, placeholder<IDX>)
{
return boost::fusion::at_c<IDX>(args);
}
template < typename ARGS
, int IDX >
typename boost::tuples::element<IDX, ARGS>::type lookup(ARGS & args, placeholder<IDX>)
{
return boost::tuples::get<IDX>(args);
}
..... cpp ...
BOOST_AUTO_TEST_CASE(lookup_check)
{
boost::fusion::vector<int, char, std::string> args(42, 'c', "Hello");
//BOOST_CHECK(lookup(args, 13) == 13);
//BOOST_CHECK(lookup(args, a3) == "Hello");
boost::tuple<int, char, std::string> args2(19, 'q', "World");
BOOST_CHECK(lookup(args2, 88) == 88);
BOOST_CHECK(lookup(args2, a2) == 'q');
}
The tuple version of course does not work with the fusion version. The fusion version results in a bunch of errors about incomplete types and such. I would expect this to be filtered out by SFINAE and use only the tuple version, but that is not happening. Why?
Here be the error output:
In file included from /usr/include/boost/fusion/include/at.hpp:10:0,
from /home/nroberts/workspace/static_binder/test/../include/bind.hpp:5,
from /home/nroberts/workspace/static_binder/test/bind_test..cpp:5:
/usr/include/boost/fusion/sequence/intrinsic/at.hpp: In instantiation of ‘boost::fusion::result_of::at<boost::tuples::tuple<int, char, std::basic_string<char> >, mpl_::int_<1> >’:
/home/nroberts/workspace/static_binder/test/bind_test.cpp:18:2: instantiated from here
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:56:16: error: invalid use of incomplete type ‘struct boost::fusion::extension::at_impl<boost::fusion::non_fusion_tag>::apply<boost::tuples::tuple<int, char, std::basic_string<char> >, mpl_::int_<1> >’
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:30:20: error: declaration of ‘struct boost::fusion::extension::at_impl<boost::fusion::non_fusion_tag>::apply<boost::tuples::tuple<int, char, std::basic_string<char> >, mpl_::int_<1> >’
I know why it might not if it had made it past the signature of the function but it has not in this case. I don't understand why it isn't just aborting this function as a non-viable overload.
Thanks.