首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板类与私有继承

模板类与私有继承
EN

Stack Overflow用户
提问于 2011-10-18 13:25:40
回答 2查看 695关注 0票数 3

为什么某些编译器坚持要求模板基类的公共成员符合条件,而对非模板类则不要求相同的成员?请查看以下代码清单:

模板类:

代码语言:javascript
复制
#include <iostream>

using namespace std;

template <class T>
class TestImpl {
public: // It wont make a difference even if we use a protected access specifier here
    size_t vval_;
    TestImpl(size_t val = 0) : vval_(val) { }
};

template <class T>
class Test : public TestImpl<T> {
public:
    Test(size_t val) : TestImpl<T>(val) {
        cout << "vval_ : " << vval_ << endl; // Error: vval_ was not declared in this scope
        //! cout << "vval_ : " << TestImpl<T>::vval_ << endl; // this works, obviously
    }
};

int main() {
    Test<int> test1(7);

    return 0;
}

非模板类:

代码语言:javascript
复制
#include <iostream>

using namespace std;

class TestImpl {
public: // It wont make a difference even if we use a protected access specifier here
    TestImpl(size_t val = 0) : vval_(val) {}
    size_t vval_;
};

class Test : public TestImpl {
public:
    Test(size_t val) : TestImpl(val) {
        cout << "vval_ : " << vval_ << endl;
    }
};

int main() {
    Test test1(7);

    return 0;
}

上述代码清单之间的显著区别是,第一个清单使用模板类,而第二个清单没有使用模板类。

现在,这两个清单都可以用微软的Visual (cl)编译,但第一个清单将不会使用Digital 和Minimalist GNUforWindows (MinGW - g++)编译器进行编译。我将得到一个类似于"vval_未在作用域中声明“的错误--这个错误我显然理解它的含义。

如果我使用TestImpl::vval_限定对TestImpl的公共变量vval_的访问,代码就会正常工作。在第二个清单中,当派生类访问基类的vval_变量时,编译器不会抱怨而不对其进行限定。

关于这两个编译器和可能的其他编译器,我的问题是,为什么我应该能够直接从从非模板类继承的非模板类直接访问(不限定)vval_变量,而我不能从从模板类继承的模板类中直接访问模板类。

EN

回答 2

Stack Overflow用户

发布于 2011-10-18 13:40:28

您必须用TestImpl<T>TestImpl<T>进行限定,以告诉编译器它取决于Test<T>T的实际类型(在Test<T>定义之前可能有一些TestImpl<T>的部分/显式专门化,并且它的实例化将改变vval_在该上下文中的意义。为了让编译器知道这一点,您必须知道vval_是依赖于(模板参数)的。

另见http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html

票数 6
EN

Stack Overflow用户

发布于 2011-10-18 14:02:10

微软.当涉及到模板代码时,他从来都不是标准兼容的,所以他是唯一的例外:)

问题是模板被分两个阶段解析:

  • 解析模板时执行第一阶段,任何不依赖(显式)模板参数的标识符都应解析为
  • 第二阶段在模板实例化

时执行。

在您的例子中,第一个阶段失败了,因为vval_不显式地依赖于模板参数(不是依赖的名称),因此它应该是可用的。

一种简单的补救方法是限定vval_ (通常与this->一起),将其标记为依赖项。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7807933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档