std::shared_ptr 隐式转换为指针类型

Implicit conversion of std::shared_ptr to pointer type

我有包装器 classes 可以包装 C 库。在本例中为 SDL。我会把所有内容都精简到必要的细节,如果有什么遗漏,请在评论中告诉我。

例如,我有一个名为 texture_t 的 class,它将包装 SDL_Texture

class texture_t
{
public:
...
private:
    SDL_Texture *tex;
}

有时,它可能在 shared_ptr:

typedef std::shared_ptr<texture_t> texture_ptr_t;

现在,如果我想调用一个以 SDL_Texture * 作为参数的 SDL 函数,我希望我的 texture_ttexture_ptr_t 隐式转换为它。

我尝试在 class:

中实现这些运算符
operator SDL_Texture *(void);
operator const SDL_Texture *(void) const;

但我仍然遇到 no viable conversion from texture_ptr_t to SDL_Texture * 错误。有人可以为我指明正确的方向吗?

即使没有 shared_ptr 和原始指针,您也会遇到这些错误,所以我暂时放弃它。

隐式转换仅适用于 texture_t 对象 ,不适用于指向对象(智能或其他)的指针。它不起作用,因为 shared_ptr 和哑指针都没有转换为不相关的指针类型。

因此,要调用任何 SDL_func 并启动转换,您需要为 texture_t 提供一个 glvalue(引用)。使用 de-reference.

即可轻松完成
SDL_func(*ptr, /* other args */); // ptr can be a dumb pointer too.

但是说了这么多,这感觉像是一个漏洞百出的抽象概念。如果您努力将 SDL_Texture* 换行,那么请不要半途而废。让 texture_t 成为一个完整的值语义类型,在 SDL 库上提供抽象的 操作 。不要因为知道您使用的是什么库而为调用代码增加负担。这将使以后需要时切换库变得更加容易。

C++ 隐式转换赋予编码器力量。一个转换运算符,一个class的接口就可以放大这么多。这是你想做的,我认为这是个好主意。

但是您应该知道,隐式转换会导致代码复杂度快速上升。美丽源于复杂,但混乱永远不会远离。所以,我们必须学会驯服野兽!那我们来练习吧。

由转换运算符实现的转换称为用户定义转换。在将参数转换为函数参数的过程中,只能进行一次用户定义的转换。所以即使 shared_ptr 有一个转换运算符指向它所持有的指针,你仍然会得到错误。

所以你必须从shared_ptr<texture_t>声明一个转换运算符,但这是不可能的,因为转换运算符必须是成员函数。因此,一种选择可能是从 shared_ptr:

派生
class texture_ptr_t
  :public std::shared_ptr<texture_t> {

  operator SDL_texture*() const{
    return *get();
    }
  };

现在你必须仔细设计这个class,这个可以通过派生到基础转换隐式转换为shared_ptr<texture_t>...也许这不是问题或者以后可能会导致问题.