Initialisierung von vector<T> in C++11



  • Mal in Code gefasst:

    struct foo {};
    struct bar {};
    
    foo operator + (foo, bar);
    
    std::vector<foo> v1;
    std::vector<bar> v2;
    
    std::vector<foo> v3; // soll jetzt die werte von v1 und v2 addiert enthalten?
    

    Habe ich dich richtig verstanden?



  • Fast: v3 soll die Inhalte von einem festen foo addiert zu allen Werten von v2 enthalten.



  • struct foo{};
    struct bar{};
    
    foo operator + (foo, bar);
    
    std::vector<foo> values;
    bar to_add;
    
    std::vector<foo> result;
    
    std:transform
    (
        values.begin(),
        values.end(),
        std::back_inserter(result),
    
        [&] (foo f)
        {
            return f + to_add;
        }
    );
    

    Sowas?



  • Fast: Es soll aber für die Initialisierung für eine *Konstante* const vector <foo> sein, d.h. es muss in eine Zeile passen.



  • std::vector<foo> gimmetheresult()
    {
        std::vector<foo> result;
        ....
        return result;
    }
    
    const std::vector<foo> myvalues(gimmetheresult());
    


  • Thx! Das scheint zu funzen.



  • Darf ich fragen womit du c++11 . Hast du ein Tutorial oder so und welchen compiler benutzt du ?

    Wurde mich sehr freuen wenn dus mir sagen konntest !



  • Ich verwende den g++ 4.6.2 auf Fedora Linux 64.



  • Wenn es Ranges gäbe, würde mir das hier fast noch besser gefallen.

    #include <iostream>
    #include <functional>
    #include <iterator>
    #include <algorithm>
    #include <vector>
    
    struct foo
    {
    	int value;
    
    	foo(int value)
    		: value(value)
    	{}
    };
    
    struct bar
    {
    	int value;
    
    	bar(int value)
    		: value(value)
    	{}
    };
    
    foo operator + (foo f, bar b)
    {
    	return foo(f.value + b.value);
    }
    
    template <typename Iterator, typename OutType>
    struct transforming_iterator : std::iterator<std::input_iterator_tag, OutType>
    {
    	typedef typename Iterator::value_type in_type;
    
    	Iterator iter;
    	std::function<OutType(in_type const&)> transform;
    
    	transforming_iterator(Iterator iter, std::function<OutType(in_type const&)> const& transform)
    		: iter(iter)
    		, transform(transform)
    	{}
    
    	OutType operator * () const
    	{
    		return transform(*iter);
    	}
    
    	transforming_iterator& operator ++ ()
    	{
    		++iter;
    		return *this;
    	}
    
    	transforming_iterator operator ++ (int)
    	{
    		transforming_iterator tmp(*this);
    		++*this;
    		return tmp;
    	}
    
    	friend bool operator == (transforming_iterator const& first, transforming_iterator const& second)
    	{
    		return first.iter == second.iter;
    	}
    
    	friend bool operator != (transforming_iterator const& first, transforming_iterator const& second)
    	{
    		return !(first == second);
    	}
    };
    
    template <typename InType, typename OutType, typename Iterator>
    transforming_iterator<Iterator, OutType> make_transforming_iterator(Iterator iter, std::function<OutType(InType const&)> const& transform)
    {
    	return transforming_iterator<Iterator, OutType>(iter, transform);
    }
    
    int main()
    {
    	std::vector<bar> bars;
    	int init = 0;
    	std::generate_n(std::back_inserter(bars), 20, [&] () { return bar(init++); });
    
    	foo const to_add(42);
    	auto transform = [&] (bar const& b) { return to_add + b; };
    
    	std::vector<foo> const foos(make_transforming_iterator<bar, foo>(bars.begin(), transform), make_transforming_iterator<bar, foo>(bars.end(), transform));
    
    	for(foo const& f : foos)
    		std::cout << f.value << '\n';
    }
    

    Und generate_n könnte man auch noch durch einen generating_iterator ersetzen. Das hätte den Vorteil, dass ich den vector<bar> nicht bräuchte, also die Werte nichtmal im Speicher liegen müssten. Iteratoren in C++ sind halt einfach sexy ❤



  • c++11 rulez schrieb:

    Ich will sowas wie

    (mapcar #'(lambda (n) (+ n 1337)) (0 1 2 3 4))
    

    haben.

    Dann baue dir doch eine mapcar-Funktion als Template, wenn dir http://www.cplusplus.com/reference/algorithm/transform/ zu lang ist.

    Fast: Es soll aber für die Initialisierung für eine *Konstante* const vector <foo> sein, d.h. es muss in eine Zeile passen.

    Dumme Begruendung. Zusaetzlich ist die Laenge einer Zeile unterschiedlich von Fall zu Fall.


Anmelden zum Antworten