std::span as a template template argument doesn't compile with clang
Asked Answered
M

2

7

I want to use std::span as a template template argument to a function. gcc seems to accept the following code, but clang rejects.

#include <iostream>
#include <span>
#include <vector>

std::vector v{1,2,3,4,5,6};

template <template <typename> class S>
S<int> GetSpan()
{
    return v;
}

int main()
{
    auto x = GetSpan<std::span>();
    return 0;
}

Can someone please explain why this is the case ?

https://godbolt.org/z/Ks9M5oqKc

Marchpast answered 21/7, 2023 at 11:27 Comment(0)
M
8

You are missing the second template parameter, the extent:

template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
    return v;
}

To make it work with a custom span-like type as well as std::span you could possibly make it take a non-type parameter pack std::size_t... or auto....

template <template <typename, std::size_t...> class S>
auto GetSpan()
{
    return S(v);
}
Melodimelodia answered 21/7, 2023 at 11:38 Comment(4)
Can I use template <template <typename...> class S> to be more generic. I need to instantiate the same function with a in-house span type which doesn't have extent argument.Marchpast
@Marchpast no, its a type and a non-type template argument. Unfortunately they dont mix wellMulticolor
But, template <template <typename, auto...> class S seems to work. I assume this can also be instantiated with MySpanType<T>.Marchpast
@Marchpast oh right, ... is 0...N thats why its fineMulticolor
M
5

std::span has two template arguments not one. Even though the second has a default, template <typename> class S is not correct, as it expects a template with only one type argument. I believe it is a gcc extension to accept the code. Anyhow this compiles also with clang:

#include <iostream>
#include <span>
#include <vector>

std::vector v{1,2,3,4,5,6};

template <template <typename,size_t> class S>  // correct template arguments
auto GetSpan()
{
    return S(v);   // ctad
}

int main()
{
    auto x = GetSpan<std::span>();
    return 0;
}

Live Demo

Multicolor answered 21/7, 2023 at 11:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.