How is it possible that this code below with conversion from std::string_view
to std::string
compiles:
struct S {
std::string str;
S(std::string_view str_view) : str{ str_view } { }
};
but this one does not compile?
void foo(std::string) { }
int main() {
std::string_view str_view{ "text" };
foo(str_view);
}
The second one gives an error: cannot convert argument 1 from std::string_view to std::string
and no sutiable user-defined conversion from std::string_view to std::string exists
.
How should I call foo()
properly?
CodePudding user response:
The constrcutor you are trying to call is
// C 11-17
template< class T >
explicit basic_string( const T& t,
const Allocator& alloc = Allocator() );
// C 20
template< class T >
explicit constexpr basic_string( const T& t,
const Allocator& alloc = Allocator() );
and as you can see, it is marked as explicit
, meaning no implicit conversion is allowed to call that constrcutor.
With str{ str_view }
you are explicitly initializing the string with the string view, so it is allowed.
With foo(str_view)
you are relying on the compiler to implicitly convert the string_view
into a string
, and because of the explicit constructor you will get a compiler error. To fix it you need to be explicit like
foo(std::string{str_view});
CodePudding user response:
How should I call foo() properly?
Like this:
foo(std::string{str_view});
How is it possible that this code below with conversion from std::string_view to std::string compiles:
It is an explicit conversion to std::string
. It can invoke the explicit converting constructor.
but this one does not compile?
It is an implicit conversion to std::string
. It cannot invoke the explicit converting constructor.