Smithy
Smithy

Reputation: 1207

C++ unique_ptr errors when mixing with C functions

I'm mixing C and C++ code and I've run into problems. Below is the code that won't compile:

unique_ptr<char[]> buf(new char[buflen]);
snprintf(buf, buflen, procfd, fd);

Resulting in the error:

wrapper_current.cpp:85:37: error: cannot convert ‘std::unique_ptr<char []>’ to ‘char*’ for argument ‘1’ to ‘int snprintf(char*, size_t, const char*, ...)’

I thought that unique_ptr looked like a normal pointer to whatever is using it. Is there a workaround for this? If using snprintf is not possible then is there some C++ method that emulates snprintf?

Upvotes: 2

Views: 454

Answers (1)

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63842

Introduction

std::unique_ptr<T> has overloads to make it feel like a raw-pointer, but it cannot implicitly turn into T* (since it has no overload of operator T). The overloaded operators of relevance are:

  • operator[]; used to access the Nth element of the underlying resource (T[] required) and;
  • operator->; used to access a member of the underlying resource, and;
  • operator *; used to get a reference to the underlying resource.

These operators acts as a "proxies" to the underlying resource, we are still invoking them on a std::unique_ptr, and buf in your example will always be of type std::unique_ptr.

Note: A unique_ptr can explicitly be converted to bool, this is to make it possible to have if (ptr) ... and related expressions; ie. making it behave like a raw-pointer would in such context.


Explanation/Solution

printf-related functions are made to work with raw-pointers, which is kinda obvious since smart-pointers aren't even a part of C (where the function originally comes from).

If you'd like to get a raw-pointer to the resource that the std::unique_ptr currently manages, suitable to be passed to printf, call your_unique_ptr.get as in the below:

snprintf (buf.get (), buflen, procfd, fd);

Upvotes: 12

Related Questions