Передайте строковый литерал аргументу функции, конструктор которого принимает только std::string_view

Предположим, у меня есть объект только с std::string_view конструктором:

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

и есть функция, которая принимает const OnlyStringViewCtor& в качестве параметра:

void f(const OnlyStringViewCtor&) {}

когда я вызываю f("hello") напрямую, возникает ошибка компилятора:

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

Есть ли какой-нибудь хороший способ, позволяющий f("hello") работать нормально и не объявлять другой конструктор, такой как OnlyStringViewCtor(const char*)?


person 康桓瑋    schedule 08.10.2020    source источник
comment
f("hello"sv) вам подходит?   -  person Dmitry Kuzminov    schedule 08.10.2020
comment
вы можете определить перегрузку f, которая принимает string_view. или позвонить f(MyClass{"test"})... может даже f({"test"}) ?   -  person Patrick Parker    schedule 08.10.2020
comment
@Dmitry Kuzminov, у меня работает, но мне просто любопытно, как не указывать sv.   -  person 康桓瑋    schedule 08.10.2020
comment
@ Патрик Паркер. f({"test"}) - хороший способ, никогда об этом не задумывался.   -  person 康桓瑋    schedule 08.10.2020


Ответы (2)


Как объясняется в другом ответе, компилятор не будет выполнять несколько неявных преобразований.

Но вы можете использовать шаблон, чтобы преодолеть разрыв:

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

person parktomatomi    schedule 08.10.2020
comment
Использование шаблона кажется хорошей альтернативой. И было бы неплохо принять концепции C++20, такие как OnlyStringViewCtor(std::convertible_to<std::string_view> auto const& string_like). - person 康桓瑋; 08.10.2020

Вызов f("hello"); невозможен. Для этого потребуется неявное преобразование из char const [6] в std::string_view, а затем еще одно неявное преобразование в OnlyStringViewCtor, но для аргумента функции разрешено только одно неявное преобразование.

Простым решением было бы вызвать f с литералом string_view, например:

using namespace std::literals;
f("hello"sv);
person cigien    schedule 08.10.2020