模板 C++ 中的范围问题 [英] Scope problems in template C++

查看:35
本文介绍了模板 C++ 中的范围问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个程序有没有范围问题?

#include使用命名空间标准;模板<类类型>班级基地{民众:类型成员;基础(类型参数):成员(参数){}};模板<类类型>派生类:public Base{民众:派生(类型参数):基础<类型>(参数){//^//|_______ 不在这里写类型会出错,为什么?}无效显示(){cout<<成员;/** 这里有错误 **/}};int main(){派生整数p(5);p.display();返回0;}

我收到错误 'member' 未在此范围内声明.如何解决问题?

解决方案

你的问题有点令人困惑.起初我以为你问的是成员初始化列表中的base,然后我以为你问的是访问member,然后又回到第一个......现在我想你两个都问,所以我两个都回答.

<小时><块引用>

不在这里写类型会出错,为什么?

当您使用类模板的名称 (my_class_templ) 时,它指的是 模板,它不是类型.为了将其用作类型,您需要提供模板参数(my_class_templ, my_class_templ).因此,无论何时需要类型名称(包括初始化列表中的基类名称),您都需要提供模板参数.

对于类模板定义中的类模板名称,您可以省略模板参数列表.例如,复制构造函数可以声明为

 my_class_templ(const my_class_templ& rhs);

代替

 my_class_templ(const my_class_templ& rhs);

这只是一个小小的语法糖,让你打字更少.

但是,在类模板定义之外,您需要明确说明所有模板参数.对于派生类也是如此:

my_dervied_class_templ(const my_derived_class_templ& rhs): my_class_templ<T>(rhs)//需要拼出<T>这里{}

<小时><块引用>

我收到错误 'member' 未在此范围内声明.如何解决问题?

当编译器第一次遇到你的模板时,只有它的定义,编译器还没有看到任何实例化.编译器不知道,在实例化的时候,范围内是否有模板的特化.但是,您可以专门为 Base<T>::member 模板引用其他内容或不完全定义.(比如说,特化Base 没有数据成员.)因此,编译器不能推测Base 的成员.因此,它们不会在 Derived 中查找.

这样做的结果是,如果你需要引用Base的成员之一,你需要告诉编译器你期望一个Base 拥有这样的成员.这是通过完全限定其名称来完成的:Base::member.

Is there any scope problem in this program?

#include<iostream>

using namespace std;

template<class Type>
class Base
{
   public:
   Type member;
   Base(Type param): member(param){

   }
};

template<class Type>
class Derived: public Base<Type>
{
    public:               
    Derived(Type param):Base<Type>(param){
     //                       ^
     //                       |_______  Not writing Type here gives error, why?
    }
    void display()
    {
        cout << member; /** ERROR HERE **/
    }
};

int main()
{
   Derived<int> p(5);
   p.display();
   return 0;
}

I get error 'member' was not declared in this scope. How to fix the problems?

解决方案

Your question is somewhat confusing. At first I thought you were asking about base<Type> in the member initialization list, then I thought you were asking about accessing member, then back to the first... Now I'm thinking you're asking both, so I'll answer both.


Not writing Type here gives error, why?

When you use a class template's name (my_class_templ), it refers to the template, which is not a type. In order to use it as a type, you need to provide template parameters (my_class_templ<int>, my_class_templ<T>). So wherever a type name is needed (and that includes the base class names in an initialization list), you need to provide template parameters.

You can omit the template parameter list for class templates names within the class template's definition. For example, a copy constructor can be declared as

 my_class_templ(const my_class_templ& rhs);

instead of

 my_class_templ<T>(const my_class_templ<T>& rhs);

This is just a little syntactic sugar, allowing you to type less.

However, outside of the class templates definition, you need to explicitly spell out all the template parameters. This is also true for derived classes:

my_dervied_class_templ(const my_derived_class_templ& rhs)
 : my_class_templ<T>(rhs)                          // need to spell out <T> here
{
}


I get error 'member' was not declared in this scope. How to fix the problems?

When your template is encountered first by the compiler, there's only its definition and no instantiations have been seen by the compiler yet. The compiler doesn't know whether, at a point of instantiation, there might be specializations of the template in scope or not. However, you could specialize your template for Base<T>::member to refer to something else or not to be defined entirely. (Say, a specialization Base<void> doesn't have a data member.) Therefore, the compiler must not speculate about the members of Base. Consequentially, they will not be looked up in Derived.

The result of this is that, if you need to refer to one of the members of Base, you need to tell the compiler that you expect a Base<T> to have such a member. This is done by fully qualifying its name: Base<Type>::member.

这篇关于模板 C++ 中的范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆