C++ 隐式地将std::shared_ptr转换为类型

C++ 隐式地将std::shared_ptr转换为类型,c++,qt,shared-ptr,implicit-conversion,C++,Qt,Shared Ptr,Implicit Conversion,假设我有一个类a,它指定转换为int struct A { int val = 42; operator int() const { return val; } 所以我可以这样使用它: A a; int a_int = a; QVariant variant = a_ptr; #include <memory> template<class T> struct shared_reference { shared_reference(std::s

假设我有一个类a,它指定转换为int

struct A {
  int val = 42;
  operator int() const {
    return val;
}
所以我可以这样使用它:

A a;
int a_int = a;
QVariant variant = a_ptr;
#include <memory>

template<class T>
struct shared_reference
{
  shared_reference(std::shared_ptr<T> pt) : _pt(std::move(pt)) {}

  operator T& () { 
    return *_pt;
  }

  operator const T& () const { 
    return *_pt;
  }

  std::shared_ptr<T> _pt;
};
但如果我想使用指向类的共享指针,该怎么办

auto a_ptr = std::shared_ptr<A>(new A);
int a_int = a_ptr; // ???

非常简单,请使用解引用运算符:

int a_int = *a_ptr; // ???
            ^ ~~~
[编辑]

使:

 QVariant variant = a_ptr;
工作时,您必须添加到QVariant复制构造函数,以接受对共享\u ptr的引用。这是你不能做的。这样的语句称为复制初始化,首先编译器尝试将一个_ptr转换为QVariant,如果它可用,则使用转换后的_ptr调用QVariant的复制构造函数。问题是,即使您取消引用一个_ptr,也需要两个用户定义的转换

您仍然可以添加如下所示的类型转换:

 QVariant variant = static_cast<int>(*a_ptr);
QVariant=static_cast(*a_ptr);

使用解引用运算符非常简单:

int a_int = *a_ptr; // ???
            ^ ~~~
[编辑]

使:

 QVariant variant = a_ptr;
工作时,您必须添加到QVariant复制构造函数,以接受对共享\u ptr的引用。这是你不能做的。这样的语句称为复制初始化,首先编译器尝试将一个_ptr转换为QVariant,如果它可用,则使用转换后的_ptr调用QVariant的复制构造函数。问题是,即使您取消引用一个_ptr,也需要两个用户定义的转换

您仍然可以添加如下所示的类型转换:

 QVariant variant = static_cast<int>(*a_ptr);
QVariant=static_cast(*a_ptr);
你试过了吗?
std::shared_ptr
具有
操作符*
,它的工作原理与预期一致:使用它

#include <memory>

struct A {
    int val = 42;
    operator int() const {
        return val;
    }
};

int main() {
    auto ptr = std::make_shared<A>();
    int v = *ptr;
}
#包括
结构A{
int-val=42;
运算符int()常量{
返回val;
}
};
int main(){
自动ptr=std::使_共享();
int v=*ptr;
}
你试过了吗?
std::shared_ptr
具有
操作符*
,它的工作原理与预期一致:使用它

#include <memory>

struct A {
    int val = 42;
    operator int() const {
        return val;
    }
};

int main() {
    auto ptr = std::make_shared<A>();
    int v = *ptr;
}
#包括
结构A{
int-val=42;
运算符int()常量{
返回val;
}
};
int main(){
自动ptr=std::使_共享();
int v=*ptr;
}
就像类型为A的变量被隐式转换为int一样,我想用智能指针做同样的事情

不,你认为你有,但你真的没有

我怎样才能做到这一点

你不能,这是件好事

(预期)有什么办法吗

将共享指针包装到对象中,如下所示:

A a;
int a_int = a;
QVariant variant = a_ptr;
#include <memory>

template<class T>
struct shared_reference
{
  shared_reference(std::shared_ptr<T> pt) : _pt(std::move(pt)) {}

  operator T& () { 
    return *_pt;
  }

  operator const T& () const { 
    return *_pt;
  }

  std::shared_ptr<T> _pt;
};
#包括
模板
结构共享\u引用
{
共享_引用(std::shared_ptr pt):_pt(std::move(pt)){
运算符T&({
返回*\u pt;
}
运算符常量T&()常量{
返回*\u pt;
}
std::共享\u ptr\u pt;
};
就像类型为A的变量被隐式转换为int一样,我想用智能指针做同样的事情

不,你认为你有,但你真的没有

我怎样才能做到这一点

你不能,这是件好事

(预期)有什么办法吗

将共享指针包装到对象中,如下所示:

A a;
int a_int = a;
QVariant variant = a_ptr;
#include <memory>

template<class T>
struct shared_reference
{
  shared_reference(std::shared_ptr<T> pt) : _pt(std::move(pt)) {}

  operator T& () { 
    return *_pt;
  }

  operator const T& () const { 
    return *_pt;
  }

  std::shared_ptr<T> _pt;
};
#包括
模板
结构共享\u引用
{
共享_引用(std::shared_ptr pt):_pt(std::move(pt)){
运算符T&({
返回*\u pt;
}
运算符常量T&()常量{
返回*\u pt;
}
std::共享\u ptr\u pt;
};

不要这样做。只需编写
*a_ptr
。新的智能指针的工作原理与普通指针一样,其中包括取消对它们的引用。在大多数情况下,运算符过载是不好的工程。请避免那样做,不要那样做。只需编写
*a_ptr
。新的智能指针的工作原理与普通指针一样,其中包括取消对它们的引用。在大多数情况下,运算符过载是不好的工程。请避免这样。我不能保存内部QVariant的实例。它太大了。我需要在那里放一个指针。每当有一个语句需要QVariant作为参数时,我都想将它转换为QVariant(并根据需要指定此转换,在某些情况下它可能相当复杂)。这改变了一切,从我所看到的情况来看,QVariant可以保持void*所以可能会强制转换一个_ptr.get()要作废*并分配给QVariant?我无法保存内部QVariant的实例。它太大了。我需要在那里放一个指针。每当有一个语句需要QVariant作为参数时,我想将它转换为QVariant(并根据需要指定此转换,在某些情况下可能会相当复杂)。这就改变了情况,从我所看到的情况来看,QVariant可以保存void*所以可能会将一个_ptr.get()转换为void*并分配给QVariant?