mikrocontroller.net

Forum: PC-Programmierung C++17 Simple if/else Konstruktion durch Variadic Template ersetzbar?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: CppBert3 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
gibt es einen elegante Möglichkeit mit C++17/Variadic templates diese 
Routine zu implementieren?
Base* implements(int id)
{
    if( id == InterfaceId<InterfaceA>::id 
        || id == InterfaceId<InterfaceC>::id ) return this;
    return nullptr;
}

für das ganze Beispiel siehe Anhang oder zum Online kompilieren: 
https://onlinegdb.com/B1fKVB0KV

Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
    if (((id == InterfaceId<Interface>::id) || ... ))
      return this;

Autor: CppBert3 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hänge noch sehr tief in C++03 und wandere langsam zu C++11...

Einfach und sehr kurz - vielen Dank

Autor: M.K. B. (mkbit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest die Methode implements() noch constexpr machen. Damit kannst 
du diese dann auch für andere Entscheidungen zur Compilezeit nutzen.

Autor: CppBert3 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gemacht - Danke

Autor: CppBert3 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch eine Frage - das pure || folding sieht ja noch einfach aus aber was 
ist wenn dazwischen noch Operationen kommen?
void typed_throw(int id)
{
    // <-- wie kann man dieses If mit C++17 aus dem Interface-Parameter pack generieren lassen?
    if( id == InterfaceId<InterfaceA>::id ) throw static_cast<InterfaceA*>(this);
    if( id == InterfaceId<InterfaceB>::id ) throw static_cast<InterfaceC*>(this);
    throw this;
}

zum Online-Kompilieren:
https://onlinegdb.com/SJRfjkf9N

gibt es da auch was in C++17

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lang aber lesbar:
  template <typename Itf>
  bool typed_throw_helper(int id) {
      if (InterfaceId<Itf>::id == id)
        throw static_cast<Itf*> (this);
      return false;
  }
  void typed_throw(int id)
  {
    static_cast<void> ((false || ... || typed_throw_helper<Interface> (id)));
    throw this;
  }
Kurz aber weniger lesbar:
  void typed_throw2(int id)
  {
      static_cast<void> ((false || ... || (InterfaceId<Interface>::id == id && (throw static_cast<Interface*> (this), true))));
      throw this;
  }

Bei "throw this" treffen aber alle "catch" Statements zu, weil Test eben 
von allen Interfaces abgeleitet wird.

Autor: Ntldr -. (ntldr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte das jetzt so gemacht:
template<typename T, typename... Args>
void typed_throw_helper(int id)
{
    if(id == InterfaceId<T>::id)
        throw reinterpret_cast<T*>(this);
    if constexpr(sizeof...(Args) > 0)
        typed_throw<Args...>(id);
    else 
        throw this;
}

void typed_throw(int id)
{
    return typed_throw_helper<Interface...>();
}

Ginge zwar auch wie oben mit einer Hilfsfunktion (die genau dann wirft, 
wenn die Id stimmt), aber das ist mMn etwas unsauberer.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ntldr -. schrieb:
> aber das ist mMn etwas unsauberer.

Kompiliert dafür aber schneller. Rekursive templates brauchen immer 
extra lange, und die maximale Tiefe ist beschränkt.

Autor: CppBert3 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Niklas G.

Danke - das mit throw this war nur Random Beispiel Code :)

Autor: M.K. B. (mkbit)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Das Video beschreibt ein Refactoring von einem ähnlichen Problem.
Relativ weit am Ende kommt der Trick indem man eine initializer List 
verwendet.

Youtube-Video "C++ Weekly - Ep 4 Variadic Template Refactor"

Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M.K. B. schrieb:
> Das Video beschreibt ein Refactoring von einem ähnlichen Problem.
> Relativ weit am Ende kommt der Trick indem man eine initializer List
> verwendet.
>
> Youtube-Video "C++ Weekly - Ep 4 Variadic Template Refactor"

Genau den Trick braucht man auf Grund von Fold-Expressions eben nicht 
mehr...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.