c++ - 使用integer_sequence 专门化模板。海湾合作委员会 vs MSVC

标签 c++ templates

所以,我遇到了一段在 GCC 和 MSVC 中表现不同的代码:

#include <utility>

typedef int IType;

template<typename> struct A;

template<int... Ns>
struct A<std::integer_sequence<IType, Ns...>> {
    using type = bool; 
};

using B = typename A<std::make_integer_sequence<IType, 3>>::type;

int main() {
    B b;
}

这可以在两个编译器上顺利编译。但是,如果您将 IType 定义为 typedef long IType; MSVC 仍然有效,而 GCC 则表示:

source>:12:61: error: invalid use of incomplete type 'struct A<std::integer_sequence<long int, 0, 1, 2> >'

   12 | using B = typename A<std::make_integer_sequence<IType, 3>>::type;

      |                                                             ^~~~

<source>:5:27: note: declaration of 'struct A<std::integer_sequence<long int, 0, 1, 2> >'

    5 | template<typename> struct A;

      |                           ^

<source>: In function 'int main()':

<source>:15:3: error: 'B' was not declared in this scope

   15 |   B b;

      |   ^

Compiler returned: 1

因此,显然当 IType 很长时,GCC 无法使用 A 的第二个更专门的定义,因此失败。我真的很难理解为什么 GCC 在这里对 intlong 进行不同的处理。

我在编译器资源管理器中使用了 GCC 10.1 和 MSVC 19.24 来玩它。 https://godbolt.org/z/7L3xap

最佳答案

std::integer_sequence 定义为

template< class T, T... Ints >
class integer_sequence;

即值的类型为T .

所以当改变IType时至long ,也是 Ns... 的类型应更改为long... :

typedef int IType;

template<typename> struct A;

template<IType... Ns>  // <--- HERE
struct A<std::integer_sequence<IType, Ns...>> {
    using type = bool; 
};

否则您将获得 struct A<long, int, int, int> 的特化与 struct A<long, long, long, long> 不匹配(MSVC 似乎对此更宽容,但在我看来,GCC 的行为更正确)。

关于c++ - 使用integer_sequence 专门化模板。海湾合作委员会 vs MSVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62634760/

相关文章:

c++ - 无法将 argv 传递给在 main 中调用的函数

jquery - 如何避免客户端和服务器端模板中的 html 重复?

c++ - 模板类可以在 C++ 中具有静态成员吗

javascript - 缩小 jQuery tmpl html 模板

c++ - Python 还是 C++?移动设备编程

c++ - const <type>& foo() 与 <type> foo()

c++ - 使用内联 ASM 进行非常规调用

C++ 嵌套类实例

c++ - 如何在模板实例化时故意导致编译时错误

c++ - 在 C++ 中创建可装饰的有效事件处理类型