3
votes

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

2
What compiler and flags are you using? Is this code sufficient to repro the problem? This works for me on Coliru once I add some semicolons.metal
Actually it works on mingw730_32.arnes
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
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

2 Answers

3
votes

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.

1
votes

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