Ambiguity between tag_invoke and others
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 45/100
Research direction
Start in include/boost/hash2/hash_append.hpp, around do_hash_append and the has_tag_invoke overload shown in the diagnostic. Reproduce the case from test_tag_invoke.cpp with the provided X and BOOST_DESCRIBE_STRUCT setup; done means it compiles without ambiguity and outputs "Called my tag_invoke".
Written by the indexing model from the issue text.
Description
It looks like the user-provided tag_invoke overload creates ambiguity if the type also matches other categories of types supported by Boost.Hash2. For example:
#include <iostream>
#include <boost/describe.hpp>
#include <boost/hash2/fnv1a.hpp>
#include <boost/hash2/hash_append.hpp>
struct X
{
int a;
template< typename Hash, typename Flavor >
friend void tag_invoke(boost::hash2::hash_append_tag const&,
Hash& h, Flavor const& f, X const& v)
{
std::cout << "Called my tag_invoke" << std::endl;
boost::hash2::hash_append(h, f, v.a);
}
};
BOOST_DESCRIBE_STRUCT(X, (), (a))
int main()
{
boost::hash2::fnv1a_32 h1;
X v1 = { 1 };
boost::hash2::hash_append( h1, {}, v1 );
}
Gcc 13.2 output:
In file included from test_tag_invoke.cpp:4:
./include/boost/hash2/hash_append.hpp: In instantiation of ‘constexpr void boost::hash2::hash_append(Hash&, const Flavor&, const T&) [with Hash = fnv1a_32; Flavor = default_flavor; T = X]’:
test_tag_invoke.cpp:25:30: required from here
./include/boost/hash2/hash_append.hpp:419:31: error: call of overloaded ‘do_hash_append(boost::hash2::fnv1a_32&, const boost::hash2::default_flavor&, const X&)’ is ambiguous
419 | detail::do_hash_append( h, f, v );
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
./include/boost/hash2/hash_append.hpp:357:5: note: candidate: ‘constexpr typename std::enable_if<boost::container_hash::is_described_class<T>::value, void>::type boost::hash2::detail::do_hash_append(Hash&, const Flavor&, const T&) [with Hash = boost::hash2::fnv1a_32; Flavor = boost::hash2::default_flavor; T = X; typename std::enable_if<boost::container_hash::is_described_class<T>::value, void>::type = void]’
357 | do_hash_append( Hash& h, Flavor const& f, T const& v )
| ^~~~~~~~~~~~~~
./include/boost/hash2/hash_append.hpp:401:5: note: candidate: ‘constexpr typename std::enable_if<boost::hash2::detail::has_tag_invoke<T>::value, void>::type boost::hash2::detail::do_hash_append(Hash&, const Flavor&, const T&) [with Hash = boost::hash2::fnv1a_32; Flavor = boost::hash2::default_flavor; T = X; typename std::enable_if<has_tag_invoke<T>::value, void>::type = void]’
401 | do_hash_append( Hash& h, Flavor const& f, T const& v )
| ^~~~~~~~~~~~~~
I think, a user-provided tag_invoke should always be preferred even if the type matches one of the natively supported type category. The code above is expected to compile and output "Called my tag_invoke".
- Dominant language
- C++
- Stars
- 52
- Forks
- 15
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from boostorg/hash2
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
Difficulty 1/5 Under an hour Newbie friendliness 35/100
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
AXERA-TECH/ax-llm#77 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
games-on-whales/wolf#509 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
bug-unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
NVIDIA/cuda-samples#453 ·