Skip to content

Fix #458: Cannot assign string to function that expects std::string_view#697

Merged
lefticus merged 2 commits into
ChaiScript:developfrom
leftibot:fix/issue-458-cannot-assign-string-to-function-that-ex
May 2, 2026
Merged

Fix #458: Cannot assign string to function that expects std::string_view#697
lefticus merged 2 commits into
ChaiScript:developfrom
leftibot:fix/issue-458-cannot-assign-string-to-function-that-ex

Conversation

@leftibot

Copy link
Copy Markdown
Contributor

Automated fix by @leftibot.

What changed

Fix #458: Support std::string_view interop with ChaiScript strings
Register std::string_view as the "string_view" user type with a built-in
implicit conversion from std::string, so a ChaiScript string can be passed
directly to a C++ function taking std::string_view. Adds the reverse
explicit conversion via string(sv) / to_string(sv), plus basic queries
(size, length, empty, data) and comparison operators on string_view.
String-style methods that take size_t (substr, find, ...) are intentionally
not duplicated on string_view: with the implicit conversion in place they
would create dispatch ambiguity for calls like string.substr(int, int).
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Files

 include/chaiscript/chaiscript_stdlib.hpp         |  6 +++++
 include/chaiscript/dispatchkit/bootstrap_stl.hpp | 34 ++++++++++++++++++++++++
 unittests/compiled_tests.cpp                     | 16 +++++++++++
 unittests/function_introspection.chai            |  5 ++--
 4 files changed, 59 insertions(+), 2 deletions(-)

Closes #458

Triggered by @lefticus.

…strings

Register std::string_view as the "string_view" user type with a built-in
implicit conversion from std::string, so a ChaiScript string can be passed
directly to a C++ function taking std::string_view. Adds the reverse
explicit conversion via string(sv) / to_string(sv), plus basic queries
(size, length, empty, data) and comparison operators on string_view.
String-style methods that take size_t (substr, find, ...) are intentionally
not duplicated on string_view: with the implicit conversion in place they
would create dispatch ambiguity for calls like string.substr(int, int).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@lefticus lefticus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leftibot why not support substr for string_view types?

@leftibot

leftibot commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

Good catch — the rationale I gave in the PR description doesn't actually hold up under scrutiny.

I claimed registering substr/find on both string and string_view would create dispatch ambiguity for calls like myString.substr(1, 2). After re-reading the dispatcher in include/chaiscript/dispatchkit/proxy_functions.hpp:793-862, that's wrong:

  1. dispatch() ranks each candidate by numdiffs (lines 803-808), preferring exact-type matches.
  2. Critically, lines 810-815 explicitly deprioritize any function whose first parameter (the receiver) requires conversion — those get numdiffs = plist.size(), the maximum penalty. The comment even spells out why ("conversions create temporaries, so mutations on the converted object are silently lost").
  3. dispatch_with_conversions is only reached as a final fallback at line 862 if every exact / near-exact candidate has failed.

So for myString.substr(1, 2):

  • string::substr(string*, size_t, size_t) — receiver matches exactly, gets the low numdiffs.
  • string_view::substr(string_view*, size_t, size_t) — receiver mismatches, gets penalized to numdiffs = plist.size().

The string overload wins; the string_view overload is never reached for a string receiver. The same logic protects find, find_first_of, etc.

There's also a real motivation to add them: string_view::substr returns a string_view, which is the whole reason script authors might want to traverse a buffer without allocating. Without substr and friends, string_view in ChaiScript is essentially a write-only sink for C++ functions that take one — which limits its usefulness.

I'd suggest a follow-up that:

  • Adds substr, find, rfind, find_first_of, find_last_of, find_first_not_of, find_last_not_of, starts_with, ends_with, and [] (random-access) to string_view_type — mirroring string_type.
  • Adds a test exercising both myString.substr(1, 2) (must dispatch to string::substr) and mySV.substr(1, 2) (must dispatch to string_view::substr and return a string_view) to lock in the dispatch behavior.
  • Keeps the lifetime caveat already noted in the doc comment — that's still accurate.

Want me to open a follow-up PR with that?

@lefticus

lefticus commented May 2, 2026

Copy link
Copy Markdown
Member

@leftibot update this pr with a more robust string_view binding

Adds substr, find/rfind/find_first_of/find_last_of/find_first_not_of/
find_last_not_of, starts_with/ends_with, and operator[] to string_view_type,
mirroring string_type's search/substring surface so script authors can
traverse a buffer through string_view without allocating.

Sharing method names with string_type creates an ambiguity in
dispatch_with_conversions when the script call needs arithmetic conversion
(e.g. myString.substr(int, int)): both string::substr and string_view::substr
match-except-for-arithmetic, and the existing const/non-const tiebreaker
doesn't apply. Extend dispatch_with_conversions to prefer the candidate
whose first/receiver parameter type exactly matches the actual receiver,
mirroring the deprioritization already in dispatch(). With this in place,
myString.substr(1, 2) still resolves to string::substr while
mySV.substr(1, 2) resolves to string_view::substr (returning a string_view).

Updates the doc comment on string_view_type and adds a compiled test that
locks in both dispatch directions plus the new search/substring methods.

Requested by @lefticus in PR ChaiScript#697 review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@leftibot

leftibot commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review feedback from @lefticus. New commits:

047e41ca Address review: expand string_view binding with substr/find/[]

@leftibot

leftibot commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

Hi @lefticus — I tried to address the review feedback but couldn't produce a working change. May need human attention.

@lefticus lefticus merged commit 46cf4cd into ChaiScript:develop May 2, 2026
21 of 22 checks passed
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

Successfully merging this pull request may close these issues.

Cannot assign string to function that expects std::string_view

2 participants