当“std::make_index_sequence”和“std::index_sequence”用于模板参数默认类型时

g++ and clang++ different behaviour when `std::make_index_sequence` and `std::index_sequence` are used for a template parameter default type

本文关键字:sequence index std 参数 默认 类型 用于 make      更新时间:2023-10-16

另一个"g++和clang++之间谁是对的?"C++标准大师的问题。

给定以下代码

#include <utility>
template <std::size_t N, typename = std::make_index_sequence<N>>
struct foo;
template <std::size_t N, std::size_t ... Is>
struct foo<N, std::index_sequence<Is...>>
 { };
template <std::size_t N>
void bar (foo<N> const &)
 { }
int main()
 {
   bar(foo<42u>{});
 }

我看到 g++ 编译,其中 clang++ 给出以下错误

tmp_003-14,gcc,clang.cpp:32:4: error: no matching function for call to 'bar'
   bar(foo<42u>{});
   ^~~
tmp_003-14,gcc,clang.cpp:27:6: note: candidate template ignored: could not match
      '__make_integer_seq' against 'integer_sequence'
void bar (foo<N> const &)
     ^
1 error generated.

像往常一样,问题是:谁是对的?g++还是clang++?

-

编辑 - 正如HolyBlackCat所指出的(谢谢!(,一些旧版本的clang++编译此代码,而较新的版本则不编译。

尝试过Wandbox,我看到clang++从3.4(支持std::make_index_sequence/std::index_sequence的第一个版本(编译到3.8.1。从 3.9.1 开始会给出上述错误。

--

编辑 2 -- 请注意,clang++ 编译错误似乎严格限制在定义第二个模板的默认值时使用第一个模板参数。

事实上,改变

template <std::size_t N, typename = std::make_index_sequence<N>>
struct foo;

// ........................... now doesn't depends from N -->VVV
template <std::size_t N, typename = std::make_index_sequence<10u>>
struct foo;

两个编译器都编译。

显然是某种 Clang/libc++ 错误:std::make_index_sequence<…> 的类型不是__make_integer_seq,而是...... std::index_sequence<…> . 类型别名(和别名模板(是透明的,尽管其默认(分配器(模板参数,但扣除始终适用于std::vector