Forum: PC-Programmierung Lambda mit return void function?


von cppbert (Gast)


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
}

von Rolf M. (rmagnus)


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.

: Bearbeitet durch User
von cppbert (Gast)


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?

von cppbert (Gast)


Lesenswert?

also eher

warum ist das valide?
1
void blub(){}
2
void test(){ return blub(); }
3
4
int main()
5
{
6
  test();  
7
  return 0;
8
}

von Rolf M. (rmagnus)


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.

von cppbert (Gast)


Lesenswert?

sowas dachte ich mir schon - Danke

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.