Modern C++ Design给出了如下例子:
template <class T> struct EnsureNotNull
{
static void Check(T*& ptr)
{
if (!ptr) ptr = GetDefaultValue();
}
};
template
<
class T,
template <class> class CheckingPolicy = EnsureNotNull,
template <class> class ThreadingModel
>
class SmartPtr
: public CheckingPolicy<T>
, public ThreadingModel<SmartPtr>
{
...
T* operator->()
{
typename ThreadingModel<SmartPtr>::Lock guard(*this);
CheckingPolicy<T>::Check(pointee_);
return pointee_;
}
private:
T* pointee_;
};
我无法想象 ThreadingModel 模板将如何以一种它可以接受 SmartPtr 作为参数的方式构建,在我看来,一些疯狂的递归将会发生。这怎么可能?
编辑:
我试过 Potatoswatter(抱歉哈哈)评论:
template <class SmartPtr> struct SingleThreadingModel
{
class Lock
{
public:
Lock(SmartPtr&)
{
}
};
};
但它没有用。
这是 gcc 给我的错误:
main.cpp:28:35: error: type/value mismatch at argument 1 in template parameter list for ‘template<class> class ThreadingModel’
main.cpp:28:35: error: expected a type, got ‘SmartPtr’
最佳答案
您正在尝试将 SmartPtr
作为模板 type 参数传递给 ThreadingModel
。然而,SmartPtr
是一个模板,而不是具体类型,injected class-name在继承列表中不可用。
另请注意,您不能只在任意位置使用模板参数的默认参数 (§14.1/11):
If a template-parameter has a default template-argument, all subsequent template-parameters shall have a default template-argument supplied.
修复了这些问题的代码:
template
<
class T,
template <class> class ThreadingModel,
template <class> class CheckingPolicy = EnsureNotNull
>
class SmartPtr
: public CheckingPolicy<T>
, public ThreadingModel<SmartPtr<T, ThreadingModel, CheckingPolicy> >
// ^ .... now passing a concrete class .... ^
{
T* operator->() {
// the following use of SmartPtr is fine as it is the injected class-name:
typename ThreadingModel<SmartPtr>::Lock guard(*this);
// ...
}
};
请注意,虽然 Modern C++ Design 是一本优秀的书,但它无法替代像 Vandevoorde/Josuttis 这样的关于模板的优秀基础书籍。 .
关于c++ - 使用模板模板类参数作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472295/