【问题标题】:Specializing template with integer_sequence. GCC vs MSVC使用 integer_sequence 专门化模板。 GCC 与 MSVC
【发布时间】:2020-06-29 09:06:54
【问题描述】:

所以,我遇到了一段在 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 的第二个更专业的定义,因此失败了。我真的很难理解为什么 intlong 在这里被 GCC 区别对待。

我在 Compiler Explorer 中使用了 GCC 10.1 和 MSVC 19.24 来使用它。 https://godbolt.org/z/7L3xap

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    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&lt;long, long, long, long&gt; 不匹配的 struct A&lt;long, int, int, int&gt; 的专业化(MSVC 似乎对此更宽松,但 GCC 的行为更正确 IMO)。

    【讨论】:

    • 请注意,clang 也采用更宽松的方法。从语言律师的角度来看,根据标准,谁在这里实际上是正确的会很有趣。
    • 对。现在,在它被回答之后,这似乎是一个非常愚蠢的问题。 =) 谢谢。
    • @DmitryBezer 我认为这是一个相当有趣的问题,尤其是在 MSVC 和 Clang 都接受此代码的情况下。这随后是 MSVC 和 Clang 中的错误吗?
    • @dfri 欢迎您使用标签language-lawyer 重新提问。可以看出,OP 目前对深入挖掘不感兴趣。
    • @ rustyx:谢谢,我尝试自己挖掘相关的标准部分,但没有成功,所以我发布了一个similar language-lawyer-tagged question,带有一个按比例缩小的示例(不包括例如模板参数包)。
    猜你喜欢
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多