Vergleichsfunktion eliminieren



  • Hallo,

    ich habe einen Struct Intron

    struct Intron {
    	std::string seq_name;	///< name of the sequence, must be a chromosom or a scaffold
    	unsigned start;	///< start position of the intron
    	unsigned end;	///< end position of the intron
    	std::string strand;	///< either + or -
    	unsigned mult;	///< multiplicity = copy number; absolute number of reads that span the intron
    };
    

    der ein Member Struct innerhalb der Klasse Genomic_Data ist. Auf Intron ist eine Vergleichsfunktion

    bool sorting_introns_s(Genomic_Data::Intron i, Genomic_Data::Intron j) { return i.start < j.start; }
    

    definiert, die z. B. so angewandt wird:

    sort(curr_genome.introns.begin(), curr_genome.introns.end(), sorting_introns_s);
    

    Ich frage mich nun, ob man sich die Funktion sorting_introns_s irgendwie sparen kann, also ob man im Aufruf von sort das letzte Argument direkt als Ausdruck formulieren kann (ich habe nämlich einige Funktionen dieser Art definiert).

    Fällt dazu jemanden was ein?



  • Das geht ab C++11 mit Lambdas.



  • Oder mit C++03 und boost.lambda, was aber etwas häßlich aussieht.



  • oder auch per Boost.Bind:

    using boost::bind;
    std::sort(
       curr_genome.introns.begin(), curr_genome.introns.end(),
       bind(&Intron::start,_1) < bind(&Intron::start,_2)
    );
    

    Beim Boost'schen bind kann man nämlich noch auf überladende Operatoren zurückgreifen, die wieder Funktoren liefern.

    In C++11 mit Lambdas ist das nicht wirklich kürzer:

    std::sort(
       curr_genome.introns.begin(), curr_genome.introns.end(),
       [](Intron const& a, Intron const& b){return a.start<b.start;}
    );
    

    Das ist mal wieder so eine Situation, wo ich denke: Schade, dass man da bei Lambdas die Typen der Parameter noch mit angeben muss. Ich hoffe, da überlegen sich die C++-Standardisierungs-Leute noch etwas schlaues, damit das kürzer geht...



  • Wenn Du meinst dass Vergleichsoperatoren für Introns sinnvoll sind, wäre es auch eine Möglichkeit, diese zu überladen.
    Z.B. bool operator<(const Intron&, const Intron&);



  • template <typename Member>
    struct compare_on_member_ {
      compare_on_member_(Member const& m) : m(m) {}
      Member m;
      template <typename T>
      bool operator()(T const& lhs, T const& rhs) const
      { return lhs.*m < rhs.*m; }
    };
    
    template <typename Member>
    compare_on_member_<Member> compare_on_member(Member m)
    {
      return compare_on_member_<Member>(m);
    }
    
    // dann:
    std::sort(vec.begin(), vec.end(), compare_on_member(&Intron::seq_name));
    std::sort(vec.begin(), vec.end(), compare_on_member(&Intron::start));
    ...
    

Anmelden zum Antworten