Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > SFINAE not applying as expected.

Thread Tools

SFINAE not applying as expected.

Noah Roberts
Posts: n/a

#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::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, 8 == 8;
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::n on_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::n on_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.

Reply With Quote
Noah Roberts
Posts: n/a

I believe I have figured out the problem. Please correct me if I'm wrong...

SFINAE only works at the most obvious level. There's a list of valid
deduction failures listed in 14.8.2 and if it's not among those then
SFINAE does not apply. The failure to instantiate some template that's
part of the template instantiation doesn't count. If I tried to access
the type that's failing within the signature I'd get a SFINAE deduction
failure and that function would be skipped. Unfortunately the deduction
of the type I'm trying to create is from within another template call
which is itself failing...and this doesn't apply.

I tested with this code:

typedef void (*A)();
struct B { typedef void type; };

template < typename T >
struct mf { typedef typename T::type type; };

template < typename T >
typename T::type f(T) {}

//template < typename T >
//typename mf<T>::type f(T) {}

template < typename T >
void f(T(*)()) {}


This code compiles and SFINAE applies because there's no type typename
within the A type. But if I comment out the first f() and uncomment the
second one (the one that uses mf), then the deduction of type depends on
the instantiation of mf, which is what fails and this doesn't trigger
Reply With Quote

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Question about "substitution failure is not an error" concept, SFINAE Aries Sun C++ 4 11-29-2007 12:54 PM
SFINAE problem. christopher diggins C++ 4 09-26-2005 06:25 PM
Using SFINAE with constructors Clark S. Cox III C++ 2 09-09-2005 09:34 PM
SFINAE compilation troubles C++ 3 02-08-2005 08:47 AM
problem with SFINAE applied to class methods Peter Collingbourne C++ 8 07-04-2004 07:25 PM