-
Notifications
You must be signed in to change notification settings - Fork 754
Fix std::hash compilation error for gsl::not_null<std::shared_ptr<T>> #1210
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
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: carsonRadtke <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes the compilation error related to the specialization of std::hash for gsl::not_null<std::shared_ptr> by changing the template deduction from decltype(.get()) to use typename T::element_type.
- Update not_null_hash template in include/gsl/pointers to correctly deduce the type.
- Add new tests in tests/notnull_tests.cpp to verify correct behavior of std::hash with not_null.
- Ensure compatibility with both C++14 and C++20 standards.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
File | Description |
---|---|
tests/notnull_tests.cpp | Added test cases to validate correct hashing behavior for not_null<std::shared_ptr>. |
include/gsl/pointers | Updated the not_null_hash template to use typename T::element_type for proper type deduction. |
|
||
|
||
template <class T, class U = decltype(std::declval<const T&>().get()), bool = std::is_default_constructible<std::hash<U>>::value> | ||
template <class T, class U = typename T::element_type, bool = std::is_default_constructible<std::hash<U>>::value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment here saying that "T
is conceptually a pointer so we don't have to worry about it being a reference and violating std::hash requirements".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the requested comment in commit 87b3085. The comment explains that T is conceptually a pointer so we don't have to worry about it being a reference and violating std::hash requirements.
…null_hash Co-authored-by: carsonRadtke <[email protected]>
The specialization of
std::hash
forgsl::not_null<std::shared_ptr<T>>
was failing to compile due to incorrect type deduction in thenot_null_hash
template.Problem
The issue occurred because the template parameter
U
was being deduced fromdecltype(std::declval<const T&>().get())
, which forgsl::not_null<std::shared_ptr<int>>
would resolve toconst std::shared_ptr<int>&
instead ofstd::shared_ptr<int>
. This causedstd::hash<const std::shared_ptr<int>&>
to not be default constructible, triggering the deleted constructor specialization.Solution
Changed the
not_null_hash
template to usetypename T::element_type
instead of deducing the type from.get()
:This directly uses the
element_type
member typedef fromgsl::not_null<T>
(which is defined asusing element_type = T;
), avoiding const/reference qualifiers that were causing the hash specialization to fail.Testing
std::hash<gsl::not_null<std::shared_ptr<T>>>
in the existingTestStdHash
testFixes #1209.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.