c++ - 类里面的模板查找?

标签 c++ templates lookup

很难用言语形容这一点。有时我会看到这样的类:

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>& 。还有什么时候隐含模板类型?如果不使用类内定义,是否允许这样编写复制构造函数?

最佳答案

语言标准在14.6.1/1中明确指定:

Within the scope of class template, when the name of the template is neither qualified nor followed by <, it is equivalent to the name of the template followed by the template-parameters enclosed in <>.

在标准的后续版本中,这一点被重新措辞(通过“注入(inject)类名”的概念),但重点是这种行为在文档中明确说明。

为了回答问题的第二部分,此规则也适用于编写类外方法定义时的参数声明,但不适用于返回类型声明。例如这段代码就可以了

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 认为这是可以的。我稍后再回来讨论。

P.P.S。 MSVC++ 2005 中的编译器提示后一个声明并发出警告

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

有趣...

关于c++ - 类里面的模板查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1704353/

相关文章:

hashmap - 如何有效地从 HashMap 中查找和插入?

python - 索引 - 使用 Pandas 匹配

c++ - 在 visual studio 2010 上使用 opencv 进行球跟踪会出现未处理的异常

c++ - 理解模板中的 const

c++ - 两个不同的 .cpp 文件中的 C/C++ 作用域

C++ 模板化 STL 容器

javascript - 带有外部 html 模板的 jsBlocks

r - R中的近似查找

c++ - 在 C++ 标准中,当我同时使用 list.begin() 作为 list.splice() 的第一个和第三个参数时,为什么会出现无限循环

C++、内部类以及为什么只能将成员创建为指向它们的指针