使用模板在size_t和int之间进行隐式类型转换

时间:2019-11-05 08:21:40

标签: c++ language-lawyer variadic-templates implicit-conversion template-specialization

我有这个编译时序列生成类(摘自here,并作了一些修改):

#include <cstddef>

template <int...>
struct sequence {};

template <int... Ns>
struct generator;

template <std::size_t Count, int... Ns>  // XXX (read below)
struct generator<Count, Ns...> {
    using type = typename generator<Count - 1, Count - 1, Ns...>::type;
};

template <int... Ns>
struct generator<0, Ns...> {
    using type = sequence<Ns...>;
};

template <std::size_t N>
using sequence_t = typename generator<N>::type;

int main() {
    sequence_t<5> a;
    return 0;
}

这在Visual Studio下可以正常编译(即使使用/permissive-开关也可以)。但这会在GCC下引发错误:

g++: error: template argument '(int)Count' involves template parameter(s)
g++:  struct generator<Count, Ns...> {
...

它也会在Clang下引发错误:

clang++: error: ambiguous partial specializations of 'generator<0, 0, 1, 2, 3, 4>'
clang++:    using type = typename generator<Count - 1, Count - 1, Ns...>::type;
...
clang++: note: partial specialization matches [with Count = 0, Ns = <0, 1, 2, 3, 4>]
clang++: struct generator<Count, Ns...> {
clang++:
clang++: note: partial specialization matches [with Ns = <0, 1, 2, 3, 4>]
clang++: struct generator<0, Ns...> {

将标记行中的size_t类型(标记为XXX (read below))更改为int之后,每个人都可以正确地编译此示例代码。

在这种情况下谁合适?是因为Visual Studio编译了代码,还是因为GCC + Clang不允许编译?

为什么Visual Studio能够很好地编译示例?它具有比其他编译器更宽松的隐式转换规则吗?还是有其他原因?任何指向我指向可以帮助我解码这些错误消息的文档的链接,也将不胜感激:)

0 个答案:

没有答案