another metaprogramming question
This seems to me like it should work. Yet the check() call resolves, without error, to the first one...which should cause an error and trigger SFINAE. Can anyone help me figure out what gives? Compiler is MSVC++ 8. Normally the SFINAE stuff works so I'm betting on my mistake this time. Basically I need to check it the metafunction meta<T> returns something. If it does then the object is a record. If it doesn't then it is not. #include <iostream> #include <boost/mpl/transform.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/mpl/vector.hpp> template < typename T1, typename T2 > struct construct_metafield_composed { typedef T1 type; // Not what the real one does. }; template < typename RECORD > struct meta { struct type : boost::mpl::transform < typename RECORD::fields , construct_metafield_composed < RECORD , boost::mpl::placeholders::_1 > >::type { typedef RECORD meta_for; }; }; template < typename T > struct is_record_check { typedef char (&no) [1]; typedef char (&yes) [2]; template < typename S > static yes check(typename meta<S>::type *); template < typename S > static no check(...); enum { value = sizeof(check<T>(0)) == sizeof(yes) }; typedef boost::mpl::bool_<value> type; }; struct test { typedef boost::mpl::vector< int, double > fields; }; int main() { // output is 1\n1\n. std::cout << is_record_check<test>::value << std::endl; std::cout << is_record_check<int>::value << std::endl; // meta<int>::type x; - yet this will cause compilation error. std::cin.get(); }
AMDG Noah Roberts wrote:
This seems to me like it should work. Yet the check() call resolves, without error, to the first one...which should cause an error and trigger SFINAE. Can anyone help me figure out what gives?
Compiler is MSVC++ 8. Normally the SFINAE stuff works so I'm betting on my mistake this time.
Basically I need to check it the metafunction meta<T> returns something. If it does then the object is a record. If it doesn't then it is not.
What do you mean by "returns something"? meta<T>::type always exists, so SFINAE doesn't apply.
template < typename RECORD > struct meta { struct type; };
<snip>
struct test { typedef boost::mpl::vector< int, double > fields; };
Would this work: BOOST_MPL_HAS_XXX_TRAITS_DEF(fields); template<typename RECORD> struct field_is_sequence : boost::mpl::is_sequence<typename RECORD::fields> {}; template<typename RECORD> struct meta : boost::mpl::and_<has_fields<RECORD>, field_is_sequence<RECORD> > {};
int main() { // output is 1\n1\n. std::cout << is_record_check<test>::value << std::endl; std::cout << is_record_check<int>::value << std::endl;
meta<int>::type exists, and since only a pointer to it is used it isn't instantiated.
// meta<int>::type x; - yet this will cause compilation error.
Now meta<int>::type is instantiated, so we get a compilation error. In Christ, Steven Watanabe
Steven Watanabe wrote:
meta<int>::type exists, and since only a pointer to it is used it isn't instantiated.
// meta<int>::type x; - yet this will cause compilation error.
Now meta<int>::type is instantiated, so we get a compilation error.
Of course. Thanks again. Your solution ideas do look like they'll do what I need.
participants (2)
-
Noah Roberts
-
Steven Watanabe