Lambda mit return void function?

Gast #6600341
Lesenswert?
• ▲
▼
wiso darf ich Lambdas return mit void machen?

clang, gcc und VS2017/19 sage das ist ok und explodieren dann beim 
Aufruf

was ist das tiefere Sinn dahinter?
1
void blub(){}
2

3
int main()
4
{
5
    auto x = []()
6
    { 
7
      // das erlaubt der Kompiler???
8
      return blub(); 
9
    };
10

11
    // das erlaubt der Kompiler nicht, völlig klar
12
    //return blub(); 
13

14
    return 0;
15
}

Cpp Insights (https://cppinsights.io/) macht das draus:
warum stört sich der Kompiler hier nicht an den return blub()s?
1
void blub(){}
2

3
int main()
4
{
5
  class __lambda_5_14
6
  {
7
    public: 
8
    inline /*constexpr */ void operator()() const
9
    {
10
      return blub();
11
    }
12
    
13
    using retType_5_14 = void (*)();
14
    inline /*constexpr */ operator retType_5_14 () const noexcept
15
    {
16
      return __invoke;
17
    };
18
    
19
    private: 
20
    static inline void __invoke()
21
    {
22
      return blub();
23
    }
24
  };
25
  __lambda_5_14 x = __lambda_5_14{};
26
  return 0;
27
}
#6600357
Lesenswert?
• ▲
▼
cppbert schrieb:
> wiso darf ich Lambdas return mit void machen?

Das hat eigentlich nichts mit Lambdas zu tun.

> clang, gcc und VS2017/19 sage das ist ok und explodieren dann beim
> Aufruf
>
> was ist das tiefere Sinn dahinter?

Der Sinn sind Templates. Es kann den Fall geben, dass man ein Template 
schreiben will, das eine Funktion aufruft, und was immer die zurückgibt, 
soll weitergegeben werden. Ohne dieses Feature würde das für alle 
Rückgabetypen außer eben void funktionieren.
Gast #6600362
Lesenswert?
• ▲
▼
ah, ok der Fehler ist nicht das ich von void returne sondern das meine 
main ein int als return-wert hat

aber trotzdem - warum wird so was nicht verhindern?
ist das wegen Templates und auto damit man da keinen Sonderweg gehen 
muss?
#6600395
Lesenswert?
• ▲
▼
cppbert schrieb:
> aber trotzdem - warum wird so was nicht verhindern?

Diese Möglichkeit wurde ganz bewusst hinzugefügt, um eben in Templates 
nicht unterscheiden zu müssen zwischen Funktionen, die void 
zurückliefern und Funktionen, die etwas andres zurückliefern.
Um mal dein Beispiel aufzugreifen:
1
void blub(){}
2
int  blah(){return 0;}
3

4
template<typename Ret>
5
struct X
6
{
7
    Ret test() { return func(); }
8
    Ret (*func)();
9
};
10

11
int main()
12
{
13
    X<void> a { blub };
14
    X<int> b { blah };
15
    
16
    a.test();
17
    return b.test();
18
}

Das würde ohne diese Möglichkeit nicht funktionieren. Man müsste extra 
eine Template-Spezialisierung der Klasse schreiben, nur um im Falle von 
Ret=void das return in test() wegzulassen.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.