代码之家  ›  专栏  ›  技术社区  ›  rlbond

在类中查找模板?

  •  2
  • rlbond  · 技术社区  · 16 年前

    template <typename T>
    class Wrapper
    {
    public:
        Wrapper(const T& t) : t_(t) {}
        Wrapper(const Wrapper& w) : t_(w.t_) {}
    private:
        T t_;
    }
    

    const Wrapper& 没有明确说明它需要 const Wrapper<T>&

    4 回复  |  直到 16 年前
        1
  •  3
  •   CB Bailey    16 年前

    语言标准14.6.1/1明确规定:

    在类模板的范围内, 既不合格也不符合<, 模板后面跟着 <>。

    template <typename T> struct S {
      S foo(S);
    };
    
    template <typename T> S<T> S<T>::foo(S s) {
      /* whatever */
    }
    

    但你不能删除 <T> 方法定义中返回类型的位。(而且你不能删除 <T> 根据方法的限定名称。)

    具体到施工人员:您应该使用全名(带 <T> )对于类,但你不应该使用 <T> 以构造函数本身的名义。因此,在你的情况下,类外定义的最短形式是

    template <typename T> Wrapper<T>::Wrapper(const Wrapper& w) : t_(w.t_)
    {
    }
    

    <T> 位到构造函数名称,即使你想

    template <typename T> Wrapper<T>::Wrapper<T>(const Wrapper& w)
                                             ^ ERROR !!!
    

    附言:最后一个说法需要进一步研究。Comeau Online编译器认为这是一个错误,而GCC认为没问题。我稍后会再回来。

    warning C4812: obsolete declaration style: please use 'Wrapper<T>::Wrapper' instead
    

        2
  •  3
  •   AnT stands with Russia    16 年前

    模板名称 因为模板被定义为完整参数化版本的简写 模板id .

        3
  •  0
  •   Brett Hall    16 年前

    在这样的模板类中,使用类名与使用 Wrapper<T> .

        4
  •  0
  •   jmucchiello    16 年前

    不,下课后你必须写:

    template <typename T>
    Wrapper<T>::Wrapper<T>(const Wrapper<T>& w) : t(w.t) {}
    

    但在课堂上, Wrapper 代表“当前班级”。

    EDIT:这是为了Andrew和他对编译器为什么会在构造函数上拒绝的调查:

    template <typename T>
    class Foo {
    public:
        Foo() {}
        Foo(const Foo& f);
    };
    
    template <typename T>
    Foo<T>::Foo<T>(const Foo<T>& f) { }
    
    int main(int argc, char** argv)
    {
        Foo<int> f;
        Foo<int> g(f); // make sure the template is instantiated
    }