Use a templated variadic template parameter as specialized parameter

c++, c++11, templates, variadic-templates

Solution

It probably boils down to this:

template<class T, class U = int>
struct cat {};

template< template<class...> class Animal >
void foo()
{
    Animal<int> x; (void)x; // (A)
}

int main()
{
    foo<cat>();
}

This little innocent-looking program is accepted by clang++ and g++, but not by MSVC2013 Update 1.

Line (A) is the problematic one: I think in this example it's clear that the template template-parameter `Animal` should have two template parameters, when passing the class template `cat`.

It seems that clang++ and g++ support the use of default template arguments for this template template-parameter in line (A), while MSVC does not.

I do not know if the Standard requires either of them; see for example

- this answer by Richard Smith

- CWG active issue #150

It certainly appears to me that supporting the default template arguments is useful, since (as said in the active issue) the class templates of the Standard Library may have additional template parameters (with default arguments); and you'd need to know those implementation-details if you wanted to use them (directly) as template template-arguments.

Problem

My title might be wrong - if so, please do correct me, but at some point its hard for me to keep track of what meta thingy I'm actually trying to achieve ;) I have a class function template like this: ``` template<template<typename...> class MapType> Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const { return SubstitutionVisitor<MapType>(identifierToExpressionMap).substitute(something); } ``` The important part is the MapType. The idea is to allow either `std::map` or `std::unordered_map` to be plugged in at will. With GCC and Clang, this works, but Visual Studio 2013 throws a compilation error: ``` error C2664: 'Expression Expression::substitute<std::map>(const MapType &) const' : cannot convert argument 1 from 'std::map<std::string,Expression,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'const std::map &' 1> with 1> [ 1> MapType=std::map 1> ] 1> and 1> [ 1> _Kty=std::string 1> , _Ty=Expression 1> ] 1> Reason: cannot convert from 'std::map<std::string,Expression,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'const std::map' 1> with 1> [ 1> _Kty=std::string 1> , _Ty=Expression 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called ``` It seems that MSVC does not put `MapType` and `<std::string, Expression>` together as a type, am I missing something here? So my question is - is this possible and just a bug in MSVC, or - is there an easier way to do this. Please keep in mind that there are many other classes which receive the `MapType` parameter and instantiate their own version with different key/value Types.

Original source

Related problems