Compile-time introspection failure

J

Juha Nieminen

I was testing the usage (or "abuse") of SFINAE for compile-time
introspection. In this particular example, I use it to call the
'reserve()' function of an object if it has it, else nothing. The
program is as follows (sorry for the somewhat lengthy program, but
I don't know if this can be implemented more briefly; please tell
me if it's possible, because it would be interesting):

//--------------------------------------------------------------------
template<typename T>
struct has_reserve_func
{
typedef char yes[1];
typedef char no[2];

template<typename size_type, void (T::*fptr)(size_type)>
struct test_struct {};

template<typename C>
static yes& test(test_struct<typename C::size_type, &C::reserve>*);

template<typename>
static no& test(...);

static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

#include <iostream>

template<bool>
struct CallReserve
{
template<typename Cont_t>
static void makeCall(Cont_t&, typename Cont_t::size_type)
{
std::cout << "Not calling reserve.\n";
}
};

template<>
struct CallReserve<true>
{
template<typename Cont_t>
static void makeCall(Cont_t& container,
typename Cont_t::size_type amount)
{
std::cout << "Calling reserve.\n";
container.reserve(amount);
}
};

template<typename Cont_t>
void callReserve(Cont_t& container, typename Cont_t::size_type amount)
{
CallReserve<has_reserve_func<Cont_t>::value>::makeCall
(container, amount);
}
//--------------------------------------------------------------------

// Test
#include <vector>
#include <list>

class Test: public std::vector<int> {};

int main()
{
std::cout << "vector: ";
std::vector<int> v;
callReserve(v, 123);

std::cout << "list: ";
std::list<int> l;
callReserve(l, 123);
}
//--------------------------------------------------------------------

When run, it prints the expected:

vector: Calling reserve.
list: Not calling reserve.

However, the "introspection" fails if the 'reserve()' function is
in a base class instead of the derived class. For example if I do
this:

//--------------------------------------------------------------------
class Test: public std::vector<int> {};

int main()
{
std::cout << "Test: ";
Testi t;
callReserve(t, 123);
}
//--------------------------------------------------------------------

it will not call the reserve function.

What is the reason for this, and can it be made to work?
 
M

Michael Doubez

  I was testing the usage (or "abuse") of SFINAE for compile-time
introspection. In this particular example, I use it to call the
'reserve()' function of an object if it has it, else nothing. The
program is as follows (sorry for the somewhat lengthy program, but
I don't know if this can be implemented more briefly; [snip: code ]
  What is the reason for this, and can it be made to work?

There has a thread recently on this topic.

The solution is using the inverse mechanism: it detects which version
of a Mixin's shadowed member function is matched.

http://www.rsdn.ru/forum/cpp/2720363.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top