C++ 在类中查找模板?

C++ 在类中查找模板?,c++,templates,lookup,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 T&T):T_(T){} 包装器(constwrapper&w):t(w.t){ 私人

这件事很难说清楚。有时我会看到这样的课程:

template <typename T>
class Wrapper
{
public:
    Wrapper(const T& t) : t_(t) {}
    Wrapper(const Wrapper& w) : t_(w.t_) {}
private:
    T t_;
}
模板
类包装器
{
公众:
包装器(const T&T):T_(T){}
包装器(constwrapper&w):t(w.t){
私人:
T!;
}

据我所知,这是合法的代码。但是,为什么复制构造函数可以接受
const包装&
,而不明确说明它需要
const包装&
。模板类型何时隐含?如果不使用类内定义,是否允许以这种方式编写复制构造函数?

基本上,在类模板定义中,您可以使用被定义为模板id完整参数化版本的缩写的模板的模板名称。

在这样的模板类中,使用类名称与使用
包装器相同,这是由语言标准明确指定的在14.6.1/1中:

在类模板的范围内, 当模板的名称为
既不合格也不紧跟否,课外你必须写:

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

在参数声明中不需要使用
包装器
。只需
包装器
就足够了。实际上,上面的说法是不正确的。在构造函数名称中使用
总是非法的。它应该是“Wrapper::Wrapper(…`。Always?在MSC6中编译得很好。很遗憾,我在工作中没有访问gcc的权限。请联机尝试Comeau。构造函数名称后的
将指示构造函数本身是模板(模板类中的模板构造函数)。在这种情况下不是这样,因此不允许使用
部分。Comeau也在其联机编译器上接受它。这是因为注入的类名在模板中工作的方式(注入的类名是在其自身范围内可见的类型的特殊名称的术语,以防止名称查找找到另一个类)。模板中注入的类名引用类模板,但如果在没有模板参数列表的情况下使用,则它引用当前正在实例化的模板的任何版本-因此在
Wrapper
中,
Wrapper
Wrapper
的同义词。可以说,将构造函数命名为
Wrapper()
更正确。我在GCC 4.4.2中尝试了这一点,但在“main1.cpp:4:error:构造函数作为模板的使用无效”中遭到拒绝。我已经回复了您的usenet问题,我认为它应该很快就会出现,并对这方面有一些想法。
template <typename T> Wrapper<T>::Wrapper(const Wrapper& w) : t_(w.t_)
{
}
template <typename T> Wrapper<T>::Wrapper<T>(const Wrapper& w)
                                         ^ ERROR !!!
warning C4812: obsolete declaration style: please use 'Wrapper<T>::Wrapper' instead
template <typename T>
Wrapper<T>::Wrapper<T>(const Wrapper<T>& w) : t(w.t) {}
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
}