代码之家  ›  专栏  ›  技术社区  ›  L. F.

为模板参数提供默认参数时,vs 2017无法正确找到以前定义的类型

  •  2
  • L. F.  · 技术社区  · 6 年前

    以下代码:

    namespace N {
        template <typename A, typename B = A>
        class Foo;
    }
    
    template <typename C, typename D>
    class N::Foo {
    public:
        Foo() = default;
    };
    
    int main()
    {
        N::Foo<char> foo;
    }
    

    涉及类模板的(转发)声明 Foo 在命名空间内 N 有两种类型参数( A B )(forward)声明为第二个参数提供与第一个参数相同的默认值。( )稍后,用不同名称的参数定义此类( C D )因为已经指定了它,所以不提供默认值。

    这在GCC 7.1和CLAN 3.8(C++ 17模式)中编译,除了未使用的变量。 foo 被警告。然而,VS 2017是7.7.5(C++ 17模式) 是未定义的标识符,并说它不是参数的有效类型名 D .

    令我惊讶的是,当我把代码改成这个时:

    namespace N {
        template <typename A, typename B = C> //note: A changed into C
        class Foo;
    }
    
    template <typename C, typename D>
    class N::Foo {
    public:
        Foo() = default;
    };
    
    int main()
    {
        N::Foo<char> foo;
    }
    

    vs接受它!(不过,它并没有在GCC或CLang中编译)

    我认为vs是错的。它试图在不同的上下文中解释默认参数(在本例中,定义 )而GCC和Clang没有。我在哪一步出错了?或者这是一个v的错误?

    任何帮助都将不胜感激。

    (抱歉我英语不好)

    2 回复  |  直到 6 年前
        1
  •  2
  •   Michael Kenzel    6 年前

    [basic.scope.temp] §3

    template <typename A, typename B = A>
    struct S;
    
    template <typename C, typename D>
    struct S {};
    
    int main()
    {
        S<int> s;
    }
    

        2
  •  -1
  •   KeepFurther    6 年前

    namespace N {
        template <typename A, typename B = A>
        class Foo;
    }
    
    template <typename A, typename B> //A and B is TYPE
    class N::Foo {
    public:
        Foo() = default;
    };
    
    int main()
    {
        N::Foo<char> foo;
    }
    

    https://docs.microsoft.com/en-us/cpp/cpp/templates-cpp

    double example(double,int);
    
    int main()
    {
    //...
    }
    
    double example(double a,double b)
    {
    //...
    }