Can a container type be displayed in variable templates?

In C ++ 11 / C ++ 14,

template <
   typename T ,
   template <typename...> class Container_t
>
void MyFunc(Container_t<T> &data) { ... }


template <typename T>
void MyFunc2( T v ) { ... }


int main()
{
   std::vector<char> v;

   MyFunc<char, std::vector>(v);     // OK
   MyFunc(v);                        // error

   int i;

   MyFunc2<int>(i);                  // OK
   MyFunc2(i);                       // OK
}

I am getting an error with MyFunc(v).

Is it possible in any way to let the compiler know the type of container passed to the variation template function? I see no problems with the search, as with regular types in regular templates.

If I need to change type v, do I need to fix all MyFunc calls?

Compiler: Microsoft Visual C ++ 2015 (v140)

+4
source share
3 answers

The trick is to name the template template arguments:

#include <vector>
#include <iostream>
#include <typeinfo>

template <
   typename T ,
   typename A,
   template <typename = T, typename = A> class Container_t
>
void MyFunc(Container_t<T, A> &data) { 
     std::cout << "value type = " << typeid(T).name() << std::endl;
     std::cout << "allocator type = " << typeid(A).name() << std::endl;
     std::cout << "container type = " << typeid(Container_t<T,A>).name() << std::endl;
   }


template <typename T>
void MyFunc2( T v ) {  }


int main()
{
   std::vector<char> v;

   MyFunc<char, std::allocator<char>, std::vector>(v);     // OK
   MyFunc(v);                        // now ok

}

If you do not need anything except the value type and the container ...

#include <vector>
#include <map>
#include <iostream>
#include <typeinfo>

template <
   typename T ,
   typename...Rest,
   template <typename, typename...> class Container_t
>
void MyFunc(Container_t<T, Rest...> &data) { 
     std::cout << "value type = " << typeid(T).name() << std::endl;
     std::cout << "container type = " << typeid(Container_t<T,Rest...>).name() << std::endl;
   }


template <typename T>
void MyFunc2( T v ) {  }


int main()
{
   std::vector<char> v;
   std::map<char, int> m;

//   MyFunc<char, std::allocator<char>, std::vector>(v);     // OK
   MyFunc(v);                        // now ok
   MyFunc(m);                        // now ok

}
+4
source

, , , , .

template <typename Container>
void MyFunc(Container& data)
{ 
   // all std containers defines value_type member (also reference etc.)
   using std::begin;
   using value_type = typename Container::value_type;
   value_type value = *begin(data);
  ...
}

, :

template <typename Container>
void MyFunc(Container& data)
{ 
   using std::begin;
   auto value = *begin(data);
  ...
}

std- ( ) - . .

+8

, V++, GCC CLANG . KerrekSB , :

template<typename T, template<typename...> class Container_t, typename... Args>
void MyFunc(Container_t<T, Args...> &data) { 
  ...
}

Live Demo

+1

All Articles