3

I want to pass a partial template specialization to template template parameter but I'm getting an error. Im not sure why excatly this doesent work.

template<template<typename, int> class V, typename T, int N, int... Indexes>
class Swizzle
{
    // ...
};

template<typename T, int N>
struct Vector;

template<typename T>
struct Vector<T, 3>
{
    // ...

    union
    {
        // ...
        Swizzle<Vector, T, 3, 0, 0, 0> xxx;
    };
};

Error:

'Vector': invalid template argument for template parameter 'V', expected a class template 'Swizzle': use of class template requires template argument list

Problem appears only on MSVC

Marek R
  • 32,568
  • 6
  • 55
  • 140
sorte33
  • 35
  • 1
  • 4
  • 1
    What compiler and flags are you using? Is this code sufficient to repro the problem? This works for me [on Coliru](http://coliru.stacked-crooked.com/a/0fefaa7c92d8cc73) once I add some semicolons. – metal Feb 04 '20 at 14:04
  • Actually it works on mingw730_32. – calynr Feb 04 '20 at 14:05
  • Im using VS2019 and fixing the missing semicolon's, still produces this error. I tried pasting the rest of my code into godbolt using clang as compiler, that works so i guess this must be a VS2019 error?. – sorte33 Feb 04 '20 at 14:16
  • offtopic: `union` in C++ code is not a best idea. Note there is `std::variant` (c++17) which is modern version of the `union`. – Marek R Feb 04 '20 at 14:39

2 Answers2

3

Within the class template Vector, Vector refers to both the type of this instance of the template and the template itself.

This should compile:

template<class X, int M>
using Self = Vector<X,M>;
// ...

union
{
    // ...
    Swizzle<Self, T, 3, 0, 0, 0> xxx;
};

I suspect MSVC is wrong here, but am uncertain.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
1

Within the class with class name injection, Vector might refer to both the type of this instance of the template and the template itself.

In the following cases, the injected-class-name is treated as a template-name of the class template itself:

[..]

  • it is used as a template argument that corresponds to a template template parameter

So Msvc is incorrect here.

Possible workaround:

Swizzle<::Vector, T, 3, 0, 0, 0> xxx;

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302