Lambda builder function
-
hatte diese keine funktion
template <typename T, typename... Ts> void emplace_back_All(std::vector<T>& vec, Ts... ts) { // "," prevents parameter pack from being folded (vec.emplace_back(ts), ...); }
welche so gecalled wird
std::vector<int> v; emplace_back_All(v, 1, 2, 3);
und wollte sie in eine lambda builder function umformen
template <typename T, typename... Ts> static auto emplace_back_All(std::vector<T>& vec) { // "," prevents parameter pack from being folded return [&](Ts... ts) { (vec.emplace_back(ts), ...); }; }
die ich dann so verwenden wollte
std::vector<int> v; auto builder{ emplace_back_All(v) }; builder(1);
allerdings sagt mit der compiler, ich habe die function mit einem Argument gecalled aber sie würde 0 erwarten. Versteht jemand wo das Problem liegt?
-
emplace_back_All(v)
Hier ist Ts ein leeres Parameterpack, und so wird
[&](Ts... ts) { (vec.emplace_back(ts), ...); }
nat. auch zu einem Lambda, dass keinen Parameter hat.
Evtl. meintest du
template <typename T> static auto emplace_back_All(std::vector<T>& vec) { // "," prevents parameter pack from being folded return [&](auto&&... ts) { (vec.emplace_back(std::forward<decltype(ts)>(ts)), ...); }; }
?
-
ja, vielen Dank, auch für die erklärung, habs verstanden.
wieso sind solche lambda builder function eigentlich static?
Habe auch noch nicht ganz verstanden, wann man ein template parameter pack benötigt und wann bbeispielsweise auto& .. ausreicht
-
Sewing schrieb:
ja, vielen Dank, auch für die erklärung, habs verstanden.
wieso sind solche lambda builder function eigentlich static?
Vermutlich wegen eines Bugs im Standard, nachdem Lambdas in verschiedenen TUs (Übersetzungseinheiten, d.h. sourcefiles) verschiedene closure Typen annehmen, und so de ODR verletzen. Siehe auch meine SO Antwort hier: https://stackoverflow.com/questions/34717823/can-using-a-lambda-in-header-files-violate-the-odr
Habe auch noch nicht ganz verstanden, wann man ein template parameter pack benötigt und wann bbeispielsweise auto& .. ausreicht
Das ist nur eine andere Syntax, weil wir Lambdas knapp und knackig halten wollen. Im closure type wird ein
operator()
template definiert, welches ein parameter pack hat. In deinem Beispiel war das parameter pack nicht im closure Typen deklariert, sondern ganz wo anders, was natürlich keinen Sinn ergibt, da das pack so nicht entsprechend deduziert werden kann.
-
das heisst, die template parameter müssen in der parameter Liste des callables auftauchen, der in der Funktion konstruiert wird?