Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In MSVC, basic_string_view<charT>::const_iterator customized type prohibits casting from a char pointer even with explicit casting. #1156

Closed
denchat opened this issue May 12, 2019 · 2 comments

Comments

@denchat
Copy link
Contributor

denchat commented May 12, 2019

When I try to use <format> using clang-target-msvc VS 2019, I got these 4 errors :

C:\Users\User\AppData\Roaming\fmt-master\include\format(611,26): error: no viable conversion from 'const char *' to
      'std::basic_format_parse_context<char>::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
    parse_ctx.advance_to(p);
                         ^
C:\Users\User\AppData\Roaming\fmt-master\include/fmt/format.h(2152,15): note: in instantiation of member function
      'std::detail::format_handler<std::detail::arg_formatter<fmt::v5::back_insert_range<fmt::v5::internal::buffer<char> > >, char,
      std::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<char> >, char> >::on_replacement_field' requested here
      handler.on_replacement_field(p);
              ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\include\xstring(851,7): note: candidate constructor
      (the implicit copy constructor) not viable: no known conversion from 'const char *' to 'const std::_String_view_iterator<std::char_traits<char> > &' for 1st
      argument
class _String_view_iterator { // iterator for character buffer wrapper
      ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\include\xstring(851,7): note: candidate constructor
      (the implicit move constructor) not viable: no known conversion from 'const char *' to 'std::_String_view_iterator<std::char_traits<char> > &&' for 1st argument
C:\Users\User\AppData\Roaming\fmt-master\include\format(153,46): note: passing argument to parameter 'it' here
    constexpr void advance_to(const_iterator it);
                                             ^
C:\Users\User\AppData\Roaming\fmt-master\include\format(618,26): error: no viable conversion from 'const char *' to
      'std::basic_format_parse_context<char>::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
    parse_ctx.advance_to(begin);
                         ^~~~~
C:\Users\User\AppData\Roaming\fmt-master\include/fmt/format.h(2161,21): note: in instantiation of member function
      'std::detail::format_handler<std::detail::arg_formatter<fmt::v5::back_insert_range<fmt::v5::internal::buffer<char> > >, char,
      std::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<char> >, char> >::on_format_specs' requested here
        p = handler.on_format_specs(p + 1, end);
                    ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\include\xstring(851,7): note: candidate constructor
      (the implicit copy constructor) not viable: no known conversion from 'const char *' to 'const std::_String_view_iterator<std::char_traits<char> > &' for 1st
      argument
class _String_view_iterator { // iterator for character buffer wrapper
      ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\include\xstring(851,7): note: candidate constructor
      (the implicit move constructor) not viable: no known conversion from 'const char *' to 'std::_String_view_iterator<std::char_traits<char> > &&' for 1st argument
C:\Users\User\AppData\Roaming\fmt-master\include\format(153,46): note: passing argument to parameter 'it' here
    constexpr void advance_to(const_iterator it);
                                             ^
C:\Users\User\AppData\Roaming\fmt-master\include\format(620,42): error: no viable conversion from returned value of type
      'std::basic_format_parse_context<char>::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >') to function return type 'const char *'
    if (visit_format_arg(f, arg)) return parse_ctx.begin();
                                         ^~~~~~~~~~~~~~~~~
C:\Users\User\AppData\Roaming\fmt-master\include\format(628,26): error: no viable conversion from 'const char *' to
      'std::basic_format_parse_context<char>::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
    parse_ctx.advance_to(begin);
                         ^~~~~
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\include\xstring(851,7): note: candidate constructor
      (the implicit copy constructor) not viable: no known conversion from 'const char *' to 'const std::_String_view_iterator<std::char_traits<char> > &' for 1st
      argument
class _String_view_iterator { // iterator for character buffer wrapper
      ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\include\xstring(851,7): note: candidate constructor
      (the implicit move constructor) not viable: no known conversion from 'const char *' to 'std::_String_view_iterator<std::char_traits<char> > &&' for 1st argument
C:\Users\User\AppData\Roaming\fmt-master\include\format(153,46): note: passing argument to parameter 'it' here
    constexpr void advance_to(const_iterator it);
                                             ^
4 errors generated.

Peeking into <format>, we are trying to convert plain char pointer to std::basic_string_view<charT>::const_iterator

  template<class charT>
  class basic_format_parse_context {
  public:
    using char_type = charT;
    using const_iterator = typename basic_string_view<charT>::const_iterator;
    using iterator = const_iterator;

In MSVC implementation, this basic_string_view<charT>::const_iterator is deliberately defined as _String_view_iterator<std::char_traits<char> > and this MSVC class template has one and only explicit private constructor from const std::char_traits<char>::chartype * which deliberately prohibits both implicit and explicit casting from const char * by outside users.

Does this mean in <format>, we must and always speak about string_view's iterators in term of basic_string_view<charT>::const_iterator when passing parameters?!?!

Does the standard have any plan to address these different approaches?

@vitaut
Copy link
Contributor

vitaut commented May 12, 2019

Fixed in 98b3775. Thanks for catching this!

@vitaut vitaut closed this as completed May 12, 2019
@denchat
Copy link
Contributor Author

denchat commented May 12, 2019

That's awesome. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants