lambda und std::is_constructable
-
Das vom GCC generierte Programm hat die richtige Ausgabe, nämlich "false". Der nutzt eben SFINAE in seiner Implementierung von
__is_nary_constructible.Der closure-Typ sieht (unoptimiert) wahrscheinlich etwa so aus:
class __lambda654 // irgendein Name { int i; __lambda654(int i) : i(i){} public: // implizit generierter Kopierkonstruktor int operator()() const {return i;} };VC++ eben.
-
Arcoth schrieb:
Ganz einfach: Die Implementierung von
std::is_constructiblewird wahrscheinlich einen Bug haben nachdem auch private Konstruktoren berücksichtigt werden. Eigentlich sollte expression-SFINAE o.ä. verwendet werden.Ich glaub ehrlich gesagt nicht, dass is_constructible private Ctors berücksichtigt.
Da müsste man sich ja schon anstrengen um das hinzukriegen.
Laut der Fehlermeldung glaub ich eher, dass der Ctor public ist und der Compiler einfach eine Fehlermeldung ausgibt, sobald man ihn aufrufen möchte.
Denn konstruiert sieht sie auf jeden Fall aus.
-
Da müsste man sich ja schon anstrengen um das hinzukriegen.
Ich habe vollstes Vertrauen in VC++.
Laut der Fehlermeldung glaub ich eher, dass der Ctor public ist und der Compiler einfach eine Fehlermeldung ausgibt, sobald man ihn aufrufen möchte.
Ja, plausibel. Wie sieht denn die Implementierung von
is_constructiblebeim VC++ aus? Laut deiner Theorie müsste durch ein Intrinsic implementiert sein.
-
Arcoth schrieb:
Laut deiner Theorie müsste durch ein Intrinsic implementiert sein.
Ist es. Wer schreibt den Bug report?
-
Du natürlich :p
-
Nö. Ich bin mit dem Template- und C++11-Zeugs zu wenig vertraut.
-
Und ich werde mich nicht bei Microsoft registrieren.
Schreib sowas:
This code:
#include <type_traits> int main() { int i = 0; auto lambda = [=]{ return i; }; static_assert( std::is_constructible<decltype(lambda), int>::value, "" ); }shouldn't compile, because declaring an object like so:
decltype(lambda) d(i);doesn't compile and isn't well-formed (which is exactly the condition that
is_constructibleshould examine).The above code does compile though.
It seems the implementation of
std::is_constructible(or the intrinsic__is_constructible, respectively) is bugged and doesn't consider the compiler magic that happens to prevent the programmer from constructing a closure object in the aforementioned way.
-
Hallo happystudent,
happystudent schrieb:
... Wenn ich dann aber sowas schreibe:
decltype(lambda) test(i);dann erhalte ich einen Fehler "error C3497: Es kann keine Instanz eines Lambdas erstellt werden".
Der VC++-Compiler scheint hier den Returnwert der lamda-Funktion und die lambda-Funktion selbst durcheinander zu würfeln.
So übersetzt z.B.:decltype(lambda) test = i;Wenn man aber schreibt:
decltype(lambda) test = irgendeinInt;dann gibt
cout << "test() = " << test() << endl;stets den Wert von 'irgendeinInt' statt den von 'i' aus.
Ein Hinweis darauf, dass der VC++-Compiler decltype(lambda) tatsächlich fälschlicherweise als int interpretiert, liefert auch:
decltype(lambda) test = 0.12;mit der Warnung: "
warning C4244: 'argument' : conversion from 'double' to 'const int', possible loss of data"Es gibt noch viel zu tun ...
Gruß
Werner
-
Werner Salomon schrieb:
Wenn man aber schreibt: […] dann gibt […] stets den Wert von 'irgendeinInt' statt den von 'i' aus.
Und was genau soll daran verwunderlich sein? Das ist das erwartete Verhalten. Der closure-Typ hat einen Konstruktor der den Member
iinitialisiert.Ein Hinweis darauf, dass der VC++-Compiler decltype(lambda) tatsächlich fälschlicherweise als int interpretiert, liefert auch: […]
Jeder Compiler gibt dir eine Warnung wenn du versuchst eine Ganzzahl mit einem Fließkomma-Literal zu initialisieren - in diesem Fall ist der
intder Konstruktorparameter.Wir können aber deine Theorie per
static_assert( std::is_convertible<decltype(lambda), int>::value, "" );überprüfen.
-
Arcoth schrieb:
Werner Salomon schrieb:
Wenn man aber schreibt: […] dann gibt […] stets den Wert von 'irgendeinInt' statt den von 'i' aus.
Und was genau soll daran verwunderlich sein? Das ist das erwartete Verhalten.
ich habe das nicht erwartet

Arcoth schrieb:
Der closure-Typ hat einen Konstruktor der den Member
iinitialisiert... so scheint es zu sein, aber wo bitteschön in den Weiten des Standards ist das beschrieben?
Gruß
Werner