The following code of mine should detect whether T
has begin
and end
methods:
template
struct is_contai
So, here's how I go about debugging these things.
First, comment out the negative alternative so you get an error instead of just a mismatch. Next, try to instantiate the type you're putting in the function with one of the items that do not work.
At this step, I was able to instantiate your sfinae object but it still wasn't working. "This lets me know it IS a VS bug, so the question then is how to fix it." -- OBS
VS seems to have troubles with SFINAE when done the way you are. Of course it does! It works better when you wrap up your sfinae object. I did that like so:
template
struct sfinae
{
// typedef typename U::const_iterator it_t; - fails to compile with non-cont types. Not sfinae
template < typename U, typename IT, IT (U::*)() const, IT (U::*)() const >
struct type_ {};
typedef type_ type;
};
Still wasn't working, but at least I got a useful error message:
error C2440: 'specialization' : cannot convert from 'overloaded-function' to 'std::_Tree_const_iterator<_Mytree> (__thiscall std::set<_Kty>::* )(void) const'
This lets me know that &U::end
is not sufficient for VS (ANY compiler) to be able to tell which end() I want. A static_cast fixes that:
typedef type_(&U::begin),static_cast(&U::end)> type;
Put it all back together and run your test program on it...success with VS2010. You might find that a static_cast is actually all you need, but I left that to you to find out.
I suppose the real question now is, which compiler is right? My bet is on the one that was consistent: g++. Point to the wise: NEVER assume what I did back then.
Edit: Jeesh... You are wrong!
Corrected version:
template
struct is_container
{
template
struct sfinae
{
//typedef typename U::const_iterator it_t;
template < typename U, typename IT, IT (U::*)() const, IT (U::*)() const >
struct type_ {};
typedef type_(&U::begin),static_cast(&U::end)> type;
};
template static char test(typename sfinae::type*);
template static long test(...);
enum { value = (1 == sizeof test(0)) };
};
#include
#include
#include
#include
#include
-- The debugging above is sensible, but the assumption about the compiler was wrong headed. G++ should have failed for the reason I emphasized above.