
There is another option that should be considered. Given that string views are cheap to copy, we could create an intermediary string view class that has all the implicit conversions and nothing else. The sole purpose of this, say, string_mediator is to convert between std::string_view and boost::string_view. This string_mediator becomes the interoperability type, and no change is needed to either std::string_view nor boost::string_view. Furthermore, no implicit conversions are needed in boost::string_view. If you want your API to support implicit conversion, then you should use string_mediator in your API. If you wish to do string operations on the string_mediator, then it should be converted into either std::string_view or boost::string_view. The following is just a simple sketch of how it could look. Obviously this should be changed into basic_string_mediator, and default, copy, and move constructor/assignment should be considered. class string_mediator { public: constexpr string_mediator(std::string_view other) noexcept : data(other.data()), size(other.size()) {} constexpr string_mediator(boost::string_view other) noexcept : data(other.data()), size(other.size()) {} operator std::string_view() noexcept { return { data, size }; } operator boost::string_view() noexcept { return { data, size }; } private: std::string_view::pointer data; std::string_view::size_type size; };