如何使用C++11初始化一个由函数结果组成的常量向量?

16

是否有可能使用类似generate_n的东西创建一个const向量,例如随机数?我想不出在不派生 vector 并在构造函数中执行赋值的方法。


2
我知道你现在已经有了答案,但是提醒一下,从vector(或者其他在std命名空间中没有特别意图被派生的类型)派生是有风险的。参考链接 - boycy
3个回答

25
如果您希望,可以使用静态助手或lambda;正如评论中指出的那样,移动语义/复制省略会使其非常便宜,因为所有良好的编译器都将省略由助手返回的向量的完全复制。相反,它们将只创建填充单个向量的代码,然后使用该向量。
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() );

这是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
有了这样一个简单的辅助工具,大多数编译器甚至可以完全省略复制操作。 - Agentlien
2
顺便提一下,根据当前标准,你的lambda需要一个-> std::vector<int>,我想。 - Christian Rau
现在我有点困惑了。尝试使用gcc4.7和cl17.00,它们都接受了它,但我似乎记得以前的版本都会拒绝它。 - stijn

0
将您的初始化封装到一个函数中,并将其声明为“constexpr”,以便您可以使用它来初始化常量表达式。

3
这里不需要使用constexpr,因为他不需要一个编译时常量表达式(而std::vector返回值永远也不可能是编译时常量表达式)。 - Christian Rau

0

你也可以使用 std::transform

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

其中 func 为:

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

这是可能的,但是OP要求一个单一的const向量。 - stijn
@stijn 噢,是的。但我可能会使用一个临时中间向量,然后将其分配给const向量,因为即使你的方法在被调用的函数中也创建了一个。 - Saksham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接