16

Is it possible to use something like generate_n to create a const vector of, say, random numbers? I couldn't think of a way to do it without deriving vector and doing the assignment in the constructor.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Emre
  • 5,976
  • 7
  • 29
  • 42
  • 2
    I know you have an answer for this now, but just FYI deriving `vector` (or other type in `std` namespace not specifically intended to be derived) is [risky](http://stackoverflow.com/questions/2034916/is-it-okay-to-inherit-implementation-from-stl-containers-rather-than-delegate) – boycy Mar 06 '13 at 13:41

3 Answers3

25

Use a static helper or a lambda if you wish; move semantics / copy elision as pointed out in the comments will make this pretty cheap since all decent compilers will omit a full copy of the vector returned by the helper. Instead they'll just create the code to fill a single vector and then use that one.

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() );

here is the lambda version:

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; 
  }() );
stijn
  • 34,664
  • 13
  • 111
  • 163
  • 1
    With such a simple helper, most compilers will even elide the copy completely. – Agentlien Mar 05 '13 at 10:44
  • 2
    By the way, according to the *current* standard your lambda needs a `-> std::vector`, I think. – Christian Rau Mar 06 '13 at 16:38
  • hmm now I'm confused. Tried with gcc4.7 and cl17.00 and they both accept it, but indeed I seem to remember previous versions of both would reject it. – stijn Mar 06 '13 at 17:03
0

Encapsulate your initialization into a function and declare it "constexpr" so that you can use it to initialize a const expression.

Cedric
  • 1
  • 3
    No need for a `constexpr` here, since he doesn't need a compile time constant expression (which a `std::vector` return can never be, anyway). – Christian Rau Mar 06 '13 at 16:40
0

You can use std::transform as well

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

Where func is:

int func(int i)
{
//return a random generated number 
}
Saksham
  • 9,037
  • 7
  • 45
  • 73
  • that's possible, but the OP asks for a single *const* vector. – stijn Aug 10 '13 at 19:38
  • @stijn Ohh yes. But I may use a temporary intermediate vector and then assign it to the `const` vector as even your approach created one in the function being called. – Saksham Aug 11 '13 at 02:23