Pass string literal to the function argument which constructor only takes std::string_view

605 views Asked by At

Suppose I have an object only has std::string_view constructor:

struct OnlyStringViewCtor {
  std::string str_;
  OnlyStringViewCtor(std::string_view str) : str_(str) {}
};

and there is a function that takes const OnlyStringViewCtor& as parameter:

void f(const OnlyStringViewCtor&) {}

when I call f("hello") directly there is a compiler error:

error: invalid initialization of reference of type 'const OnlyStringViewCtor&' from expression of type 'const char [6]'

Is there some nice way that can let f("hello") work fine and not declare another constructor such as OnlyStringViewCtor(const char*)?

3

There are 3 answers

1
parktomatomi On BEST ANSWER

As the other answer explained, the compiler won't do multiple implicit conversions.

But, you can use a template to bridge the gap:

struct OnlyStringViewCtor {
  std::string str_;
  template<typename T, std::enable_if_t<std::is_constructible_v<std::string, T>, int> = 0>
  OnlyStringViewCtor(T str) : str_(str) {}
};

https://godbolt.org/z/1reajv

1
cigien On

The call f("hello"); is not possible. This would need an implicit conversion from char const [6] to std::string_view, and then one more implicit conversion to OnlyStringViewCtor, but only one implicit conversion is allowed for a function argument.

A simple fix would be to call f with a string_view literal, like this:

using namespace std::literals;
f("hello"sv);
0
dev-here On

Second answer on this post was good, but the namespace could be corrected:

using namespace std::string_view_literals;
f("hello"sv);