0

I want to have a certain function that does a computation if the Argument is a certain template with a specific first template parameter (arbitrarily templated).

Consider these classes

template<class S> struct A { };
template<class S> struct B { };
template<class S> struct C { };
template<class S, class U = B<S>> struct D { };

I tried to achieve my goal using

template<template<class ... X> class Y, class Z>
inline void foo(Y<A<Z>> const &av) { std::cout << "2\n"; }

Problem: MSVS 2013 is not able to deduce Y.

int main()
{
  foo(C<A<int>>()); // prints 2 as intended
  foo(D<A<int>>()); // does NOT compile in VS 2013
  return 0;
}

The reason for the error (according to MSVS) is:

template-Argument for const Y<A<Z>> & cannot be deduced from D<A<int>, B<S>> with S=A<int>.

My goal is to write an overload / specialization that handles any given type Y where Y::value_type / the first template parameter of Y can be any A<T> where the signature of foo is to be preserved: void foo (Y const &);

Is this a Bug in MSVS (since foo(D<A<int>>()); does in fact print 2 using g++) or am I missing something?

PS: Merry Christmas if you care...

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71

1 Answers1

3

D<A<int>, B<S>> is not Y<A<Z>>, you have to add the extra parameter:

template<template<class...> class Y, class Z, typename ... Ts>
inline void foo(Y<A<Z>, Ts...> const &av) { std::cout << "2\n"; }

Where Ts... can be empty.

An alternative is to make a alias:

template <typename T>
using E = D<A<T>>;

and then

foo(E<A<int>>()); // OK, but still can't use foo(D<A<int>>());
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • The moment when you're told: "You were hit by the truck of obviousness"... :) Thanks a lot. (Eventhough, I'm still puzzled by the different behavior of gcc and VS.) – Pixelchemist Dec 25 '14 at 20:30