【发布时间】:2019-11-05 08:21:40
【问题描述】:
我有这个编译时序列生成类(取自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 能够很好地编译示例?它是否比其他编译器具有更宽松的隐式转换规则?还是有其他原因?任何可以将我指向可以帮助我解码这些错误消息的文档的链接也将不胜感激:)
【问题讨论】:
-
好的,我已经为你添加了 [language-lawyer] 标签。
标签: c++ language-lawyer variadic-templates implicit-conversion template-specialization