So at the moment I have:
std::string a;
std::unique_ptr<char[]> b(std::make_unique<char[]>(a.size() + 1));
std::copy(std::begin(a), std::end(a), b.get());
Is it is possible to initialize this directly in one step?
So at the moment I have:
std::string a;
std::unique_ptr<char[]> b(std::make_unique<char[]>(a.size() + 1));
std::copy(std::begin(a), std::end(a), b.get());
Is it is possible to initialize this directly in one step?
Is it is possible to initialize this directly in one step?
I would suggest keeping it as std::string
or std::vector<char>
.
However, if you really insist, Yes! Using an immediately invoking a lambda, this can be done.
std::unique_ptr<char[]> b = [&a]() {
auto temp(std::make_unique<char[]>(a.size() + 1));
std::copy(std::begin(a), std::end(a), temp.get());
return temp;
}(); // invoke the lambda here!
The temp
will be move constructed to the b
.
If the string a
will not be used later, you could move it to the std::unique_ptr<char[]>
, using std::make_move_iterator
.
#include <iterator> // std::make_move_iterator
std::unique_ptr<char[]> b(std::make_unique<char[]>(a.size() + 1));
std::copy(std::make_move_iterator(std::begin(a)),
std::make_move_iterator(std::end(a)), b.get());
If that needs to be in one step, pack it to the lambda like above.
Here's a variation using strdup
and a custom deleter.
Note the use of char
as first template parameter to std::unique_ptr
rather than char[]
since strdup
will be giving back a char*
.
The custom deleter is used to free
memory rather than delete
it, since strdup
will use some flavor of malloc
rather than new
to allocate memory.
And you certainly don't need to use the typedef
(or using
, if you prefer) for CustomString
here; it's just provided for sake of brevity.
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
int main()
{
// Some reusable utility code for a custom deleter to call 'free' instead of 'delete'.
struct CustomDeleter
{
void operator()(char* const p) const
{
free(p);
}
};
typedef std::unique_ptr<char, CustomDeleter> CustomString;
const std::string a("whatever");
// "Concise" one step initialization...
const CustomString b(_strdup(a.c_str()));
return 0;
}
Not advocating this as an ideal way to do this, but wanted to share as "a way" to do the one step initialization you asked for.