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.