简体   繁体   中英

Implicit conversion of std::shared_ptr to pointer type

I have wrapper classes that will wrap a C Libary. In this case SDL. I'll shorten everything down to the neccessary details, if something is missing, please tell me in the comments.

So for example I have a class called texture_t which will wrap SDL_Texture

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

Sometimes, it may be in a shared_ptr :

typedef std::shared_ptr<texture_t> texture_ptr_t;

Now if I want to call a SDL function that takes a SDL_Texture * as an argument, I want my texture_t and texture_ptr_t to implicitly convert to it.

I tried implementing these operators in my class:

operator SDL_Texture *(void);
operator const SDL_Texture *(void) const;

But I still get no viable conversion from texture_ptr_t to SDL_Texture * errors. Can someone point me in the right direction for getting this right?

You'd get those errors even in the absence of a shared_ptr , with a raw pointer, so I'll forego it for a moment.

The implicit conversion is applicable only from a texture_t object , not from a pointer to one (smart or otherwise). It doesn't work because neither a shared_ptr nor a dumb pointer has this conversion to an unrelated pointer type.

So to call any SDL_func and have the conversion kick in, you need to provide a glvalue (a reference) to a texture_t . It's easily accomplished with a de-reference.

SDL_func(*ptr, /* other args */); // ptr can be a dumb pointer too.

But having said all that, this feels like a leaky abstraction. If you made the effort to wrap SDL_Texture* , then don't stop at a half measure. Have texture_t be a fully value semantic type that provides abstracted operations over the SDL library. Don't burden calling code with knowing what library you use. It will make it all the more easier to switch libraries later should it be needed.

C++ implicit conversion gives power to the coder. With a single conversion operator, one can enlarge so much the interface of a class. This what you want to do and I think it is a good idea.

But you should know that implicit conversions lead to a fast rise in code complexity. Beauty arise from complexity, but chaos is never far. So, we must learn to master the beast! So let's practice.

Conversions implemented by conversion operators are called user defined conversion. In the process of converting the argument to the function parameter, only one user defined conversion can take place. So even if shared_ptr had a conversion operator to the pointer it hold, you would still get the error.

So you must declare a conversion operator from shared_ptr<texture_t> , but that is impossible because conversion operators must be member functions. So one option could be to derive from shared_ptr :

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

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

Now you have to carefully design this class, this one is implicitly convertible to shared_ptr<texture_t> through derived to base conversion... Maybe it is not an issue or maybe it will cause problem later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM