std::span 作为模板模板参数不能用 clang 编译

aep*_*aep 7 c++ templates clang clang++ c++17

我想用作std::span函数的模板模板参数。gcc 似乎接受以下代码,但 clang 拒绝。

#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;
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会出现这种情况吗?

https://godbolt.org/z/Ks9M5oqKc

Ted*_*gmo 8

您缺少第二个模板参数,即范围:

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

为了使其与自定义span类型一起工作,std::span您可以使其采用非类型参数包std::size_t...auto....

template <template <typename, std::size_t...> class S>
auto GetSpan()
{
    return S(v);
}
Run Code Online (Sandbox Code Playgroud)


for*_*818 5

std::span有两个模板参数而不是一个。即使第二个有默认值,template <typename> class S也是不正确的,因为它期望一个只有一种类型参数的模板。我相信这是一个接受代码的 gcc 扩展。无论如何,这也可以用 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;
}
Run Code Online (Sandbox Code Playgroud)

现场演示