0

This is a followup of Vector of pairs with generic vector and pair type, template of template.

I'd like to be able to call a method with a std::vector or stxxl:vector, while template arguments of the vector (Pair of x,y) are specified.

Specifically the method signatrue might look like this:

template<typename t_x, typename t_y,
            template<typename, typename> class t_pair,
            template<typename...> class t_vector>
    method(t_vector<t_pair<t_x,t_y>> &v) 

Unfortunately when specifying the signature like this, it is not possible to pass a stxxl:vector as t_vector. It leads to the following compile error:

sad.hpp:128:5: note:   template argument deduction/substitution failed: 
program.cpp:104:52: error: type/value mismatch at argument 1 in template parameter list for ‘template<class ...> class t_vector’
         method(coordinates);
                           ^ 
program.cpp:104:52: error:   expected a type, got ‘4u’ 
program.cpp:104:52: error: type/value mismatch at argument 1 in template parameter list for ‘template<class ...> class t_vector’ 
program.cpp:104:52: error:   expected a type, got ‘2097152u’

The question is how to modify the method signature in order to be able to use stxxl::vector as a drop-in replacement for existing code using std::vector?

Update on why I'm using nested templates for the vector: I might be mistaken, but I'd like the compiler which types for the variables in the aforementioned method.

I'm for example building a vector or a queue

std::vector<t_x> intervals(k * k + 1);
typedef std::tuple<std::pair<t_x,t_y>,std::pair<t_x,t_y>, std::pair<t_x,t_y>, uint> t_queue;
std::queue <t_queue> queue;

Which should either be uint32_t or uint64_t depending on wether the type of the pair-elements is uint32_t or uint64_t

Community
  • 1
  • 1
Jan B
  • 518
  • 1
  • 3
  • 18
  • Why do you need to specify the template parameters like that? Why not just use a simple `typename t_vector` without all the others parameters? Having a template template parameter is useful if you are going to use this template parameter to construct various type, but in your case you only use it with one type which is `t_pair`. – Holt Jul 18 '16 at 06:53
  • I'm using uint32_t and uint64_t as the template parameter of pair. I'm therefore using t_x/t_y in my code to decide wether 32/64 Bit Integers should be used. – Jan B Jul 18 '16 at 06:57
  • I don't really see why having the template the way you do against the simple form will help you with that? Could you update your question to show us exactly why you need to have such template parameters (and why the simpler form does not work for you)? – Holt Jul 18 '16 at 06:59
  • @Holt thanks for your answers so far, I hope I clarified my intentions with the update of the question – Jan B Jul 18 '16 at 07:07
  • Thanks for the update, see my updated answer for a (I think better) way of doing what you want. – Holt Jul 18 '16 at 07:13

1 Answers1

3

The problem is that stxxl::vector has non-type template parameter:

BlockSize external block size in bytes, default is 2 MiB

So it cannot be match against template <typename... >.

You should not use a template template parameter in this case, something like this would be better (I think):

template <typename t_vector>
void method (t_vector &v) {
    typedef typename t_vector::value_type::first_type t_x;
    typedef typename t_vector::value_type::second_type t_y;
    // or in c++11 and above
    typedef decltype(v[0].first) t_xd;
    typedef decltype(v[0].second) t_yd;
}

In the above, you retrieve t_x and t_y either using:

  • value_type which is something that all Container should have (both std::vector and stxxl::vector have it);
  • decltype which directly gets the type from the expression v[0].first (works even if v is empty since the expression inside decltype is never evaluated).

From my experience, it is better to use a very generic template argument and then retrieve information from it (value_type, decltype, ...) than trying to constraint the template argument itself with given types.

Holt
  • 36,600
  • 7
  • 92
  • 139