auto und Zugriff auf typedef



  • Hi,

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    vector<int> getVec() { return {}; }
    
    int main()
    {
    	auto vec = getVec();
    
    	for_each(begin(vec), end(vec), [](decltype(vec)::value_type &v){});
    }
    

    mir ist decltype(vec) zu lang, gibts da keine schöne Abkürzung?



  • mir ist decltype(vec) zu lang, gibts da keine schöne Abkürzung?

    Nein.



  • Naja, du kannst es so schreiben:

    decltype(vec[0])
    

    (ungetestet! ginge ja, falls nicht mit Indexop., auch mit at )
    :xmas2:
    Aber das decltype(vec) kannst du damit eben nicht verkürzen.



  • Ja stimmt, ganz vergessen. Der statische Typ von vec[0] steht ja dann schon fest. Würde es template lambdas geben, könnte ich nur T hinschreiben und auch sowas schönes machen:

    #include <list>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    list<int> getList() { return {}; }
    vector<int> getVec() { return {}; }
    
    int main()
    {
    	auto vec = getVec();
    	auto lis = getList();
    
    	auto func = [](auto &v) { };
    
    	for_each(begin(vec), end(vec), func(decltype(vec)::value_type));
    	for_each(begin(vec), end(vec), func(decltype(lis)::value_type));
    }
    

    😞



  • So waere es mir viel lieber:

    auto func = []<T>(T &v) { };
    
    for_each(begin(vec), end(vec), func<decltype(vec)::value_type>);
    for_each(begin(vec), end(vec), func<decltype(lis)::value_type>);
    

    Edit: oder eben kürzer:

    // klappt auch wenn keine element drin ist, da statischer Typ angeschaut wird
    for_each(begin(vec), end(vec), func<decltype(vec[0])>);
    for_each(begin(vec), end(vec), func<decltype(lis[0])>);
    


  • Es gibt leider noch keine polymorphic lambdas. Link 1 Link 2
    In den Links wird unter anderem erklärt, was das Problem an

    std::transform(first, last, result, [](x){return x*2;});
    

    ist.

    decltype ist übrigens etwas kritisch, bei Identifiern, weil da noch Referenzen und dabei sein könnten. Besser wäre hier

    iterator_traits<decltype(begin(vec))>::value_type
    


  • Danke für die Links. Ich glaub', ich implementiere mal das ganze auch in Clang:

    auto func = []<T>(T &v) { }; 
    
    for_each(begin(vec), end(vec), func<int>); 
    for_each(begin(vec), end(vec), func<char>);
    

    wird nach einer source-to-source transformation zu:

    auto func_int = [](int &v) { }; 
    auto func_char = [](char &v) { };
    
    for_each(begin(vec), end(vec), func_int); 
    for_each(begin(vec), end(vec), func_char);
    

    Sollte doch gehen, oder? Müsste nur aufpassen, dass der Bezeichner func_int/char nicht schon im Programm exisitiert. Ist ja aber erstmal egal, oder ich waehle halt kryptische Namen.



  • KasF schrieb:

    Sollte doch gehen, oder?

    Das Lambda wird ja zu einem Archetype. Ich würde bevorzugen, dass

    auto func = [](auto& v) { };
    
    for_each(begin(vec), end(vec), func);
    for_each(begin(vec), end(vec), func);
    

    zu

    struct __lambda_func // reservierter Bezeichner, muss frei sein
    {
        template <class T> void operator()(T x) { }
    };
    
    auto func = __lambda_func{};
    
    for_each(begin(vec), end(vec), func);
    for_each(begin(vec), end(vec), func);
    

    wird. Das ist schöner und wahrscheinlich näher an den polymorphic Lambdas in C++42 dran.



  • Jep, akzeptiert.



  • Da ist dir gestern jemand zuvorgekommen:
    http://faisalv.github.com/clang-glambda/


Anmelden zum Antworten