当`std :: make_index_sequence`和`std :: index_sequence`用于模板参数默认类型时,g ++和clang ++的行为不同

时间:2019-07-21 12:22:54

标签: c++ c++14 variadic-templates template-specialization template-deduction

另一个“谁在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;

两个编译器都进行编译。

1 个答案:

答案 0 :(得分:0)

这显然是某种Clang / libc ++错误:类型std::make_index_sequence<…>不是__make_integer_seq,而是…std::index_sequence<…>。类型别名(和别名模板)是透明的,并且推论对std::vector一直有效,尽管它是默认的(分配器)模板参数。

相关问题