seqan/seqan3

gcc13: specialization after instantiation

eseiler opened this issue · 0 comments

E.g., https://cdash.seqan.de/viewBuildError.php?buildid=56001

The include order in the kmer_hash_test reveals an issue.

I boiled it down to:

// Inside SDSL
#include <functional>
#include <string>

void instantiate_me()
{
    std::hash<std::string> h{};
    (void) h;
}

// Inside SeqAn3
#include <ranges>
#include <seqan3/alphabet/concept.hpp>

namespace std
{
template <std::ranges::input_range urng_t>
    requires seqan3::semialphabet<std::ranges::range_reference_t<urng_t>>
struct hash<urng_t>
{};
}

#include <seqan3/alphabet/adaptation/char.hpp>

int main()
{}

What happens now is:

  • std::hash<std::string> will use our specialisation of std::hash for semialphabets
  • semialphabet will check for validity of seqan3::to_rank(v) where v is of type char
  • to_rank is a CPO and will instantiate unconstrained seqan3::custom::alphabet<char>
  • Including char.hpp offers a constrained version (specialization) of seqan3::custom::alphabet<char>
error: partial specialization of ‘struct seqan3::custom::alphabet<t>’ after instantiation of ‘struct seqan3::custom::alphabet<char>’

Ideas:

  • Changing include order:
    • Doesn't seem like a general fix
  • Declaring the constrained version when declaring the unconstrained version:
    • Would basically require to include the adaptations after the general class template has been defined.
  • Rethink/Check for what types we want to overload/specialize std::hash

Note:
Relevant STL https://eel.is/c++draft/temp.expl.spec#7.sentence-2 :

If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required.