策略转换仅适用于构造函数
#include "stdafx.h"
#include <exception>
template<class T>
class NoCheck;
template<class T>
class EnforceNotNull
{
public:
//EnforceNotNull(const NoCheck<T>&){}//<<-----If this is uncommented it works
static void Check(T* p)
{
class NullPtrException : public std::exception
{
};
if (!p)
{
throw NullPtrException();
}
}
};
template<class T>
class NoCheck
{
public:
NoCheck(){}
NoCheck(const NoCheck&){}
NoCheck(const EnforceNotNull<T>&){}
operator EnforceNotNull<T>() {return EnforceNotNull<T>();}//<<-----This seams to not do its job
static void Check(T* p)
{/*Empty body*/}
};
template<class T, template<class> class CheckingPolicy>
class SmartPtr : public CheckingPolicy<T>
{
public:
SmartPtr(T* p)
{
Check(p);
}
template<class T1, template <class> class CheckingPolicy1>
SmartPtr(const SmartPtr<T1,CheckingPolicy1>& pattern):pointee_(pattern.pointee_),
CheckingPolicy<T>(pattern)
{
}
T* pointee_;
private:
};
int _tmain(int argc, _TCHAR* argv[])
{
SmartPtr<int,NoCheck> p1(nullptr);
SmartPtr<int,EnforceNotNull> p = p1;//I'm trying here to convert NoCheck to
// EnforceNotNull but it works for me only if I use ctor, if I use conversion optor
//(from
// NoCheck to EnforceNotNull) it doesn't work why?
return 0;
}
#include "stdafx.h"
#include <exception>
template<class T>
class NoCheck;
template<class T>
class EnforceNotNull
{
public:
//EnforceNotNull(const NoCheck<T>&){}//<<-----If this is uncommented it works
static void Check(T* p)
{
class NullPtrException : public std::exception
{
};
if (!p)
{
throw NullPtrException();
}
}
};
template<class T>
class NoCheck
{
public:
NoCheck(){}
NoCheck(const NoCheck&){}
NoCheck(const EnforceNotNull<T>&){}
operator EnforceNotNull<T>() {return EnforceNotNull<T>();}//<<-----This seams to not do its job
static void Check(T* p)
{/*Empty body*/}
};
template<class T, template<class> class CheckingPolicy>
class SmartPtr : public CheckingPolicy<T>
{
public:
SmartPtr(T* p)
{
Check(p);
}
template<class T1, template <class> class CheckingPolicy1>
SmartPtr(const SmartPtr<T1,CheckingPolicy1>& pattern):pointee_(pattern.pointee_),
CheckingPolicy<T>(pattern)
{
}
T* pointee_;
private:
};
int _tmain(int argc, _TCHAR* argv[])
{
SmartPtr<int,NoCheck> p1(nullptr);
SmartPtr<int,EnforceNotNull> p = p1;//I'm trying here to convert NoCheck to
// EnforceNotNull but it works for me only if I use ctor, if I use conversion optor
//(from
// NoCheck to EnforceNotNull) it doesn't work why?
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我根本不明白为什么 SmartPtr 必须从检查策略继承。我也不明白为什么政策本身必须是一个模板。
为什么不简单地:
I don't see why the SmartPtr has to be inherited from the checking policy at all. Nor do I see why the policy has to be a template itself.
Why not simply:
您的
operator EnforceNotNull()
函数不是const
,因此编译器不会将其包含在可能的转换函数集中。取消注释EnforceNotNull
copy ctor 或在上述函数上添加const
,您的代码应该可以工作。Your
operator EnforceNotNull<T>()
function is notconst
, so the compiler isn't including it in the set of possible conversion functions. UncommentEnforceNotNull
copy ctor or put aconst
on the above function and your code should work.您的代码看起来有点过于复杂。例如,您不必继承策略,除非它关心某些状态,而这不是您的情况。另外,拥有类需要放置访问说明符,因此使用结构可能会更好。
无论如何,智能指针不能被复制,这是主要技巧。您只能转让所有权(动产概念)。所以你的复制构造函数有点不正确。如果这显然是您的意图,您可能仍然拥有它,但请确保您有一些参考计数器。
这是您的代码,已简化并可运行:
以下是您如何使用 MPL 强制转换:
Your code looks a little bit overcomplicated. For example, you don't have to inherit a policy unless it cares some state, which is not your case. Plus, having classes requires putting access specifiers, so you might be better off with structs.
Anyways, smart pointers cannot be copied, that is the main trick. You can only transfer ownership (movable concept). So your copy constructor is a bit incorrect. You may still have it if that is clearly your intent, but make sure you have some reference counter whatsoever.
Here is your code, simplified and working:
Here is how you enforce conversions using MPL: