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_t
和 texture_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>
...也许这不是问题或者以后可能会导致问题.
我有包装器 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_t
和 texture_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>
...也许这不是问题或者以后可能会导致问题.