首页 文章

是否允许在允许用作模板类型的函数内使用内联类? [重复]

提问于
浏览
3

这个问题在这里已有答案:

我在成员函数(构造函数)Foo中定义了一个类Bar,我试图将其用作模板参数 .

template<typename Ty>
struct Spam {
    template<class U, class D> Spam(U*, D) {}
};
struct Foo {
    Foo() {
        struct Bar {};
        int *ptr = NULL;
        Spam<int> pSpam(ptr, Bar());
    }
};

我的猜测是用法无效,因为Bar的范围是Foo的本地范围,并且不能具有模板实例化所需的全局可见性 . 但是在第二种情况下,我在Bar的相同范围内实例化模板,虽然模板类/结构是全局的,但模板实例不应存在任何可访问性问题 .

我尝试了多个编译器,每个编译器的行为都不同 . 尤其

  • clang接受警告
warning: template argument uses local type 'Bar' [-Wlocal-type-template-args]
  • VC编译时没有警告

  • GCC 4.3.4编译失败

10 : error: no matching function for call to 'Spam::Spam(int*&, Foo::Foo()::Bar)'
3 : note: candidates are: Spam::Spam(const Spam&)
  • GCC C 14编译成功

根据标准,预期的行为是什么?

1 回答

  • 3

    C 2003标准14.3.1 / 2指定

    本地类型,没有链接的类型,未命名的类型或从这些类型中的任何类型复合的类型不得用作模板类型参数的模板参数 .

    template <class T> class X { /* ... */ };
    void f()
    {
       struct S { /* ... */ };
       X<S> x3; // error: local type used as template-argument
       X<S*> x4;  // error: pointer to local type used as template-argument
    }
    

    但它允许在C 11及更高版本中使用 .

    N3797 14.3.1 / 2

    template <class T> class X { };
    template <class T> void f(T t) { }
    struct { } unnamed_obj;
    void f() 
    {
       struct A { };
       enum { e1 };
       typedef struct { } B;
       B b;
       X<A> x1; // OK
       X<A*> x2; // OK
       X<B> x3; // OK
       f(e1); // OK
       f(unnamed_obj); // OK
       f(b); // OK
    }
    

相关问题