看effective C++条款43随手做的实践。
#include <iostream>
template <typename T>
class InType{
private:
T _val;
public:
InType(const T & val) : _val(val)
{ }
T & val()
{
return _val;
}
};
template <typename T>
class InTypeWithLog : public InType<T>{
public:
using InType<T>::InType;
T & val_and_log()
{
std::cout << "call val_and_log" << std::endl;
//using InType<T>::val;
//this->
//Intype<T>::val(); 书中不推荐这个做法,会使多态失效
return InType<T>::val();
}
};
int main()
{
auto a = InTypeWithLog<int>(10);
std::cout << a.val_and_log();
return 0;
}
假设我们不对25行做处理,我们会得到这样的一个报错
'val' 没有依赖于模板参数的参数,因此声明 'val' 必须可用
关于为什么编译器拒绝这样的代码,书中写的很详细了,这里就简单的说一下。
模版基类有可能被特例化,这个特例化版本可能没有提供使用的接口,本例中就是val这个接口。
面对基类中的成员失效,可能会有两种情况,一种是早期的检查基类中无此方法,再者就是稍后期的特例化版本没有此方法,C++的做法是尽早的检查错误,这就是为什么基类从模版中被具体化的时候,假设它对那些基类的内容毫无所悉的缘故。