Templates and higher-order kinds in C++

c++, higher-kinded-types, templates

Solution

Compiler has already told you what is wrong (errors from ideone):

prog.cpp:25:24: error: non-template 'instance_wrapper' used as template prog.cpp:25:24: note: use 'C1::template instance_wrapper' to indicate that it is a template

Use `C1::template instance_wrapper` instead of `C1::instance_wrapper` - and, similarly, do the same for `C2::instance_wrapper`:

template <typename T, typename C1, typename C2>
void move(typename C1::template instance_wrapper<T>::instance& c1, 
    typename C2::template instance_wrapper<T>::instance& c2)
{
    // ...

It's because `C1` is template and compiler cannot deduce that `instance_wrapper` is template and treats it as non-template type.

Please, please, read everything compiler outputs. Not just line-by-line. Often compiler says what's wrong in one of previous or following lines, as in this case, when it's already giving you the answer!

Problem

I am trying to write a function that takes two containers of the same contained type, e.g., two `std::vector<int>`s, or a `std::list<int>` and a `std::vector<int>`. (But not a `std::vector<int>` and a `std::vector<double>`!) Since I am not quite sure regarding how it should be done, I decided to write a test progam first: ``` #include <iostream> #include <vector> #include <list> #include <algorithm> struct vector_wrapper { template <typename T> struct instance_wrapper { typedef typename std::vector<T> instance; }; }; struct list_wrapper { template <typename T> struct instance_wrapper { typedef typename std::list<T> instance; }; }; template <typename T, typename C1, typename C2> void move(typename C1::instance_wrapper<T>::instance& c1, typename C2::instance_wrapper<T>::instance& c2) // line 29 { while (c1.size() > 0) { c2.push_front(c1.back()); c1.pop_back(); } } int main() { std::vector<int> v; std::list <int> l; v.reserve(10); for (int i = 0; i < 10; ++i) v.push_back(i); move<int, vector_wrapper, list_wrapper>(v, l); std::for_each(l.begin(), l.end(), [] (int i) { std::cout << i << " "; } ); std::cout << std::endl; return 0; } ``` This code gives me the following compile-time error with g++ 4.7, using the `-std=c++11` flag: ``` metaclass.cpp:29:24: error: non-template 'instance_wrapper' used as template ... more ... ``` Why does the compiler not correctly identify `instance_wrapper` as a template?

Original source