views:

57

answers:

1

What type signature would I need to use if I'd like to determine the type returned by an array (T)'s subscript operator using boost? Note that the arrays for which I would be using this do not contain typedefs and are third-party.

Example. I want to determine that:

SomeArray<int> tmp(1);  
int& somevalue = tmp[0]; //would equate  
typename subscript_result<SomeArray<int> >::type somevalue = tmp[0];

Something like

template<class T>
struct subscript_result
{
  typedef boost::result_of<T::operator[](typename T::difference_type)>::type type;
};

? I've always had trouble with operator[] in type signatures. :|

Thank you!

A: 

Perhaps you could use BOOST_TYPEOF / BOOST_TYPEOF_TPL: http://www.boost.org/doc/libs/1_35_0/doc/html/typeof/refe.html#typeof.typo

BOOST_TYPEOF(tmp[0]) i;

In C++0x, you should be able to use decltype(tmp[0]) i;


In answer to the comment. Perhaps you can trick it to not remove const and references with something like that:

#include <boost/typeof/typeof.hpp>

template <class T>
struct identity
{
    typedef T type;
};

template <class T>
struct subscript_result
{

    template <class Result, class Obj, class Arg>
    static identity<Result> get_subscript_type(Result (Obj::*)(Arg));

    typedef BOOST_TYPEOF(get_subscript_type(&T::operator[])) aux;
    typedef typename aux::type type;
};

#include <vector>
#include <iostream>

template <class Container>
void foo(Container& c)
{
    typename subscript_result<Container>::type t = c[0];
    ++t;
}

int main()
{
    //prove that foo gets a reference to vector<int>
    std::vector<int> vec(1);
    foo(vec);
    std::cout << vec[0] << '\n';
}

You'll probably also need to come up with something for const overloads, as well as throw in specializations for arrays / pointers.

UncleBens
Looks like it might have been useful if BOOST_TYPEOF/_TPL included referencedness and cv-qualification as part of the result.. So close, damn.
Geoff
@Geoff can't you use type_traits `is_const`, `is_volatile`, and `is_reference` to find referencedness and cv-qualification? Then use that as part of a template specialization to declare something as `typedef typename const BOOST_TYPEOF(get_subscript_type(` or `typedef typename BOOST_TYPEOF(get_subscript_type(` ?
KitsuneYMG