为什么某些编译器坚持要求模板基类的公共成员符合条件,而对非模板类则不要求相同的成员?请查看以下代码清单:
模板类:
#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;
}非模板类:
#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_变量,而我不能从从模板类继承的模板类中直接访问模板类。
发布于 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
发布于 2011-10-18 14:02:10
微软.当涉及到模板代码时,他从来都不是标准兼容的,所以他是唯一的例外:)
问题是模板被分两个阶段解析:
时执行。
在您的例子中,第一个阶段失败了,因为vval_不显式地依赖于模板参数(不是依赖的名称),因此它应该是可用的。
一种简单的补救方法是限定vval_ (通常与this->一起),将其标记为依赖项。
https://stackoverflow.com/questions/7807933
复制相似问题