The first approach is the answer. Per standard §21.4.2:
basic_string(const charT* s, const Allocator& a = Allocator());
9 Effects: Constructs an object of class basic_string and determines its initial string value from the array of charT of length
traits::length(s)
whose first element is designated by s...
and
10 Remarks: Uses
traits::length()
.
gcc's implementation is:
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _CharT* __s, const _Alloc& __a)
: _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
__s + npos, __a), __a)
{ }
It uses traits_type::length
which is something like std::char_traits::length
to discover length of c-style zero terminated strings.
If you have huge entry string to pass the function and you have it's length, you can use another overload which gets the size and doesn't calculate it again:
basic_string(const CharT* s, size_type count, ...)
The second approach that you've mentioned has another disadvantage, it has to shrink the allocate memory to stop wasting memory. This operation is expensive also.