2013-03-05 14 views
17

Czy można użyć czegoś takiego jak generate_n, aby utworzyć const vector, powiedzmy, liczb losowych? Nie mogłem wymyślić sposobu, aby to zrobić bez wyprowadzania vector i wykonywania przypisania w konstruktorze.Jak zainicjowałbyś wektor const wyników funkcji używając C++ 11?

+2

Wiem, że masz odpowiedź na to teraz, ale po prostu FYI wynikające 'vector' (lub innego rodzaju w' przestrzeń nazw std ", która nie jest przeznaczona do wyprowadzenia) jest [ryzykowne] (http://stackoverflow.com/questions/2034916/is-it-okay-to-inherit-implementation- from-stl-containers-rather-than-delegate) – boycy

Odpowiedz

26

Użyj statycznego pomocnika lub lambda, jeśli chcesz; przesuń semantykę/copy elision, jak wskazano w komentarzach, sprawi, że będzie to dość tanie, ponieważ wszystkie przyzwoite kompilatory pominą pełną kopię wektora zwróconego przez pomocnika. Zamiast tego będą po prostu tworzyć kod, aby wypełnić pojedynczy wektor, a następnie użyć go.

std::vector<int> Helper() 
{ 
    const size_t n = 10; 
    std::vector<int> x(n); 
    std::generate_n(x.begin(), n, someGenerator); 
    return x; 
} 

const std::vector<int> my_const_vec(Helper()); 

tutaj jest wersja lambda:

const std::vector<int> my_const_vec([]() 
    { 
    const size_t n = 10; 
    std::vector<int> x(n); 
    std::generate_n(x.begin(), n, someGenerator); 
    return x; 
    }()); 
+1

Przy tak prostym pomocniku większość kompilatorów całkowicie wymusi kopiowanie. – Agentlien

+2

Przy okazji, zgodnie z * bieżącym * standardem, twoja lambda potrzebuje '-> std :: vector ', jak sądzę. –

+0

hmm teraz jestem zdezorientowany. Próbowałem z gcc4.7 i cl17.00 i obaj to akceptują, ale wydaje mi się, że pamiętam poprzednie wersje obu, które by je odrzuciły. – stijn

0

enkapsulacja inicjalizacji do funkcji i uznaniu jej za „constexpr”, dzięki czemu można używać go zainicjować const wyraz.

+3

Nie ma tu potrzeby "constexpr", ponieważ nie potrzebuje on kompilacji wyrażenia stałej czasowej (której zwrot "std :: vector" nigdy nie może być, tak czy inaczej). –

0

Można użyć std::transform także

vector<int> vec(10,1); 
transform(vec.begin(), vec.end(), vec.begin(), func); 

Gdzie func jest:

int func(int i) 
{ 
//return a random generated number 
} 
+0

to jest możliwe, ale OP prosi o pojedynczy * const * wektor. – stijn

+0

@stijn Ohh tak. Ale mogę użyć tymczasowego wektora pośredniego, a następnie przypisać go do wektora 'const', nawet jeśli twoja metoda stworzyła jedną z wywoływanych funkcji. – Saksham