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?
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 constructor.
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});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With