【发布时间】:2013-10-08 08:34:27
【问题描述】:
我决定测试“Effective C++”中的一个示例,但没有得到预期的结果。所以,显然这个(简化的)代码不应该编译:
template <class T>
struct A {
void f(){}
};
template <class T>
struct B : public A <T> {
void f2() { f(); } // calling base function - will not compile
};
以下是解释(为简单起见更改了类名):
上面的代码不能编译,至少不能使用符合标准的编译器。这样的编译器会抱怨
f不存在。我们可以看到f在基类中,但是编译器不会在那里寻找它。我们需要了解原因。 问题是当编译器遇到类模板
B的定义时,他们 不知道它继承自哪个类。当然是A<T>,但是T是一个模板参数, 一个直到稍后才会知道(当B被实例化时)。不知道是什么T也就是说,没有办法知道A<T>的类是什么样的。特别是,无法知道它是否具有f函数。
我的编译器 (Visual Studio) 不介意...它甚至不显示任何警告。
上面的代码是否正确?
【问题讨论】:
-
f() 需要完全限定为基类名称或
this-> -
@Troy "f() 需要完全合格.." 抱歉这是什么意思?
-
@Oleksiy 它适用于 MSVC,因为该编译器没有实现两阶段名称查找,因此不会在模板实例化之前尝试解析依赖名称。在实例化时,
A<T>::f不再是从属名称,因为T是已知的。而完全合格意味着如果你写A<T>::f(),它就会起作用。 C++-faq 解释了使用这种方法的缺陷。 -
@Praetorian:完全合格 言过其实。调用必须是依赖的,这可以通过添加
this->或qualifying 来实现。无需完全限定调用,只需要基本类型。
标签: c++ templates inheritance base