Compiler Error bei Function Template mit VS2010 SP1



  • Hallo,

    Das untenstehende Bsp. erzeugt den markierten Compiler Error (getestet mit VS2010SP1). Dieselbe Semantik mit einem for-Loop und ohne Lambda kompiliert ohne Probleme.

    - Ist der Compiler Error berechtigt? [geklärt, siehe unten]
    - Ist es korrekt das ADL bei begin(..) und end(..) greifen sollte? [geklärt]
    - Sind noch 2 typenames nötig bei source_container_type::value_type bzw. target_container_type::value_type? [geklärt, editiert]

    #include <list>
    #include <vector>
    #include <algorithm>
    
    template <typename source_container_type, typename target_container_type>
    void copy_all(const source_container_type& source, target_container_type& target)
    {
        std::for_each(begin(source), end(source), [&] (const typename source_container_type::value_type& element)
        {
            // error C2899: typename cannot be used outside a template declaration
            // error C2653: 'target_container_type' : is not a class or namespace name
            target.push_back(typename target_container_type::value_type(element));
        });
    }
    
    int main()
    {
        std::vector<int> a;
        a.push_back(23);
        a.push_back(24);
        a.push_back(25);
    
        std::list<int> b;
        copy_all(a, b);
    }
    

    Vielen Dank
    Theta

    Antwort
    Der Compiler Error ist ein Bug im VS2010 SP1:
    MS Connect: http://connect.microsoft.com/VisualStudio/feedback/details/694857/bug-in-lambda-expressions
    StackOverflow Diskussion: http://stackoverflow.com/questions/9466338/compiler-error-in-function-template-with-vs2010-sp1

    [edit, 0] typenames im Bsp. Code ergänzt
    [edit, 1] 1. typename im Bsp. Code korrigiert
    [edit, 2] Nach den ersten 2 Edits tritt zusätzlich noch Error C2899 auf.
    [edit, 3] Frage bezüglich ADL als geklärt markiert.
    [edit, 4] Frage bezüglich Compiler Error als geklärt markiert. Siehe Antwort oben.



  • Ja, es fehlen die typenames. Ja, ADL greift hier. Aber warum nicht einfach so?

    std::copy(begin(src), end(src), std::back_inserter(dest));
    

    Oder:

    std::list<int> dest(begin(src), end(src));
    


  • Aber warum nicht einfach so? ...

    Der Code ist ein Bsp. und es geht um das Prinzip.



  • Warum zeigst du Code, den du so gar nicht verwendest?

    Anyway, dein typename ist falsch gesetzt. Richtiger wäre

    const typename source_container_type::value_type&
    

    , ganz korrekt ist:

    typename source_container_type::const_reference
    


  • Hat jmd. ev. noch eine Erklärung zum oben erwähnten Compiler Error?



  • theta schrieb:

    Hat jmd. ev. noch eine Erklärung zum oben erwähnten Compiler Error?

    Ne, aber das geht:

    template <typename source_container_type, typename target_container_type>
    void copy_all(const source_container_type& source, target_container_type& target)
    {
        typedef typename target_container_type::value_type vtype;
        std::for_each(begin(source), end(source), [&] (const vtype& element)
        {
            target.push_back(vtype(element));
        });
    }
    

    Edit: Warum auch immer man hier for_each nutzen möchte. Ich muss leider sagen, dass ich die alte for Schleife hier noch besser finde. (Im Gegensatz zu Sutter scheinbar.., na ja, wenn die ranged-based for-loops endlich überall verfügbar sind, wird die eh jeder nutzen.)



  • Ok, danke. Ich muss vielleicht meine Frage präzisieren:
    Meiner Meinung nach sollte mein Code ohne Probleme kompilieren - die Frage ist ob er das gemäss Standard C++11 wirklich sollte?

    Die Antwort bezüglich Compiler Error ist in der Frage eingepflegt.


Anmelden zum Antworten