开发者

Complex type deduction from function template parameter

I have another C++ template question. I am a lazy guy, so I try to not specify template arguments if possible. Now I have a function

template< typename EasyLookingObject >
void myfunct( EasyLo开发者_JS百科okingObject& obj ) {
  //do something with obj
}

Now, EasyLookingObject is in fact a

boost::ptr_list< A< STDContainer::<TargetType*> > >

In order to work with obj, I need to know the types of STDContainer and TargetType. Can you help me to get these types?

Problem 1: EasyLookingObject::value_type does give me a pointer type. How do I deduce the full type from it and use it within a typedef?

The same probably applies to the STDContainer::value_type issue.


Removing the pointer is trivial using partial specialisation:

template <typename T>
struct remove_ptr {
    typedef T type;
};

template <typename T>
struct remove_ptr<T*> : remove_ptr<T> { };

(I’m sure Boost also has something like this.)

Putting it all together:

typedef typename remove_ptr<typename EasyLookingObject::value_type>::type a_t;
typedef typename a_t::container_type container_t;
typedef typename remove_ptr<typename container_t::value_type>::type target_t;


Problem 1: EasyLookingObject::value_type does give me a pointer type. How do I deduce the full type from it and use it within a typedef?

You probably don't need to extract the typedefs.

Just pass every extracted item to another overloaded function. Use an extractor function akin to boost::get_pointer() to extract a pointer from a reference, or a plain or smart pointer.

template<class Container>
void do_something_item(Item* item); // overload for different types as necessary

template<class Container>
void do_something(Container& c) {
    for(typename Container::iterator i(c.begin()), j(c.end()); i != j; ++i) {
        using boost::get_pointer; 
        do_something_item(get_pointer(*i)); // use ADL to find get_pointer() overload
    }
}


If you really can't infer the correct types from class typedefs (which I doubt, double check the documentation), the you can specify the template parameters a bit more explicitly:

template <template <typename...> class Container, typename T, typename ...Args>
void myfunc(const Container<T*, Args...> & c)
{
  // ...
}

If you don't have variadic templates, you'll have to specify as many arguments as your container takes, or specify default arguments if you only want the template to match those. Here's a defaulting version that works for two-parameter containers:

template <template <typename A, typename = std::allocator<A> > class Container,
          typename T>
void myfunc(const Container<T*> & c);

This will only match Container<T*, std::allocator<T*>>. Here's a general version for two-parameter containers:

template <template <typename , typename> class Container,
          typename T1, typename T2>
void myfunc(const Container<T1*, T2> & c);

Concretely, your function should be a variation of this:

template <template <typename> class Container, typename T>
void myfunc(const boost::ptr_list<A<Container::<T*> > > &);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜