C++ 为什么非常量ptr不能作为模板中的参数隐式转换为常量ptr

C++ 为什么非常量ptr不能作为模板中的参数隐式转换为常量ptr,c++,C++,我只是尝试实现std::auto_ptr,我的声明如下 template<typename T> class auto_ptr_imp { public: explicit auto_ptr_imp<T>(T const* rhs=NULL); auto_ptr_imp(auto_ptr_imp<T>&); auto_ptr_imp& operator =(auto_ptr_imp<T>&); T&a

我只是尝试实现std::auto_ptr,我的声明如下

template<typename T>
class auto_ptr_imp
{
public:
   explicit auto_ptr_imp<T>(T const* rhs=NULL);
   auto_ptr_imp(auto_ptr_imp<T>&);
   auto_ptr_imp& operator =(auto_ptr_imp<T>&);
   T& operator*();
   T* operator->();
private:
   T* m_ptr;
};
template<typename T>
auto_ptr_imp<T>::auto_ptr_imp(T * ptr)
  {
    this->m_ptr=ptr;
  }

//in main function call this 
 auto_ptr_imp<ClassA>ptr(new ClassA(2)); //compile error
 int*p=NULL;
 int const* pp=p;//no error
模板
类自动\u ptr\u导入
{
公众:
显式auto_ptr_imp(T const*rhs=NULL);
auto_ptr_imp(auto_ptr_imp&);
auto_ptr_imp&operator=(auto_ptr_imp&);
T&算子*();
T*运算符->();
私人:
T*m_ptr;
};
模板
auto_ptr_imp::auto_ptr_imp(T*ptr)
{
这->m_ptr=ptr;
}
//在main函数中调用
自动输入(新A类(2))//编译错误
int*p=NULL;
int const*pp=p//无误
然后出现错误:“=”:无法将“const ClassA*”强制转换为“ClassA*”


但我记得当将非常量指针指定给常量指针时,会发生隐式转换。下面的代码很复杂。这让我感到困惑。

如果您可以将“指针指向
常量
对象”类型的值分配给指向非
常量
对象的指针,那么您可以通过该指针修改
常量
对象。当然,这是错误的


但是,如果您将指向非
const
对象的指针指定给指向
const
对象的指针,那么您只是承诺,尽管对象是可修改的,但您不会修改它。突变不是强制性的,所以这很好。

我想你是想声明:

explicit auto_ptr_imp<T>(T const* rhs=NULL);
explicit auto_ptr_imp(T const*rhs=NULL);
因此:

explicit auto_ptr_imp<T>(T * const rhs=NULL);
explicit auto_ptr_imp(T*const rhs=NULL);

请记住,
const T*
T const*
是相同的-指向
const T
的非常量指针。只有
T*const
是指向非常量
T

的常量指针,即使在修复语法错误后,我也不会从您发布的代码中得到该错误。很可能,您的构造函数实现(您忘了向我们展示)正在尝试从
rhs
初始化
m_ptr
,这将不起作用,因为这需要删除
const
限定符。但是在没有看到导致错误的代码的情况下,我只能猜测。
auto\u ptr\u imp
没有定义为类模板@MikeSeymour感谢您的警告。正如您所说,当我从rhs分配m_ptr时,实际上发生了错误。当询问无法编译的内容时,请确保包括实际失败的代码行以及错误代码。通过隐藏错误消息及其发生位置,您没有帮任何人的忙。声明的参数类型
explicit auto_ptr_imp(T const*rhs=NULL)与定义不匹配。如果没有发布实际代码及其产生的实际错误,您将得到-1。我假设没有人希望声明第二个签名,因为顶级const volatile限定符将从签名中删除,并且构造函数声明将实际上是
显式auto_ptr_imp(T*rhs=NULL)
(除了在析构函数体内部——但不是针对调用方——不能修改参数。@DavidRodríguez dribeas嗯,我个人倾向于在函数定义中将参数声明为
const
,如果我不打算修改它们,以捕捉潜在的错误(例如意外地使用参数而不是数据成员)。但我同意这并不常见。尽管如此,这似乎是最可能的解释,特别是考虑到OP如何区分“非常量指针”和“指向常量的指针”。:)在我看来,
main
int const*pp=p;//没有错误
中的比较似乎他真的想要一个指向const对象的非常量指针。但是,他遇到这个问题的事实再次表明,
const
对他来说不是很清楚