C++ 如何初始化静态向量成员?

C++ 如何初始化静态向量成员?,c++,static,lambda,C++,Static,Lambda,比如说 struct A { static vector<int> s; }; vector<int> A::s = {1, 2, 3}; 结构A { 静态向量s; }; 向量A::s={1,2,3}; 但是,我的编译器不支持初始化列表。有什么方法可以轻松实现它吗?lambda函数在这里有用吗?我总是担心在这里因为类似的问题而被击倒 #include <iostream> #include <vector> #include <

比如说

struct A
{
    static vector<int> s;
};

vector<int> A::s = {1, 2, 3};
结构A { 静态向量s; }; 向量A::s={1,2,3};
但是,我的编译器不支持初始化列表。有什么方法可以轻松实现它吗?lambda函数在这里有用吗?

我总是担心在这里因为类似的问题而被击倒

#include <iostream>
#include <vector>
#include <iterator>

struct A
{
    static std::vector<int> s;
};

static const int s_data[] = { 1,2,3 };
std::vector<int> A::s(std::begin(s_data), std::end(s_data));

int main()
{
    std::copy(A::s.begin(), A::s.end(), 
              std::ostream_iterator<int>(std::cout, " "));
    return 0;
}

仅仅因为你能,并不意味着你就应该

以最低效的方式获奖:

#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;

template<typename T>
std::vector<T> v_init(const T& t)
{
    return std::vector<T>(1,t);
}

template<typename T, typename... Args>
std::vector<T> v_init(T&& t, Args&&... args)
{
    const T values[] = { t, args... };
    std::vector<T> v1(std::begin(values), std::end(values));
    return v1;
}

struct A
{
    static std::vector<int> s;
};

std::vector<int> A::s(v_init(1,2,3,4,5));


int main(int argc, const char *argv[])
{
    std::copy(A::s.begin(), A::s.end(), std::ostream_iterator<int>(std::cout, " "));
    return 0;
}

如果T和Args中的任何内容。。。不符合类型或类型浇注料。当然,如果你有可变模板,那么很可能你也有初始化列表,但如果没有其他东西,它会让大脑变得有趣。

你可以从两个指针初始化一个
std::vector

int xv[] = {1,2,3,4,5,6,7,8,9};
std::vector<int> x(xv, xv+(sizeof(xv)/sizeof(xv[0])));
intxv[]={1,2,3,4,5,6,7,8,9};
向量x(xv,xv+(sizeof(xv)/sizeof(xv[0]));
您甚至可以在模板函数中考虑这一点:

template<typename T, int n>
std::vector<T> from_array(T (&v)[n]) {
    return std::vector<T>(v, v+n);
}
模板
std::来自_数组的向量(T(&v)[n]){
返回std::向量(v,v+n);
}

为向量编写一个简单的初始化函数:

vector<int> init()
{
  vector<int> v;
  v.reserve(3);
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  return v;
};

vector<int> A::s = init();
vector<int> A::s = [] {
    vector<int> v;
    v.push_back(1);
    v.push_back(2); 
    v.push_back(3);
    return v;
}();
vector init()
{
向量v;
v、 储备(3);
v、 推回(1);
v、 推回(2);
v、 推回(3);
返回v;
};
向量A::s=init();
有什么方法可以轻松实现它吗

没有什么特别优雅的。您可以从静态数组复制数据,也可以使用函数调用的结果对其进行初始化。前者可能会使用比您希望的更多的内存,而后者需要一些稍微混乱的代码

Boost有一个让它稍微不那么难看的方法:

#include <boost/assign/list_of.hpp>
vector<int> A::s = boost::assign::list_of(1)(2)(3);
#包括
向量A::s=boost::assign::list_of(1)(2)(3);
lambda函数在这里有用吗

是的,它可以使您不必仅为初始化向量而命名函数:

vector<int> init()
{
  vector<int> v;
  v.reserve(3);
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  return v;
};

vector<int> A::s = init();
vector<int> A::s = [] {
    vector<int> v;
    v.push_back(1);
    v.push_back(2); 
    v.push_back(3);
    return v;
}();
向量A::s=[]{ 向量v; v、 推回(1); v、 推回(2); v、 推回(3); 返回v; }(); (严格地说,这应该有一个显式的返回类型,
[]()->vector
,因为lambda主体包含的不仅仅是一个
返回
语句。一些编译器会接受我的版本,我相信它将在2014年成为标准。)

另一个想法:

struct A
{
  static std::vector<int> s;
};

std::vector<int> A::s;

static bool dummy((A::s.push_back(1), A::s.push_back(2), A::s.push_back(3), false));
结构A { 静态std::向量s; }; std::向量A::s; 静态bool dummy((A::s.push_-back(1),A::s.push_-back(2),A::s.push_-back(3),false));
boost::列表中的
非常棒。但是我必须使用的
boost::assign::list_让它工作。事实上,我的向量是
vector
下面的向量没有内存泄漏吗<代码>向量A::s=boost::assign::list_of(newint(2))
@user1899020:对不起,我忘了分配
部分;自从大括号初始化出现后,我就没有使用过该库。@user1899020:
unique\u ptr
初始化应该可以,只要它编译并且没有任何分配失败。因为这是初始化一个静态对象,失败将结束程序,所以不需要特别担心泄漏。更一般地说,您应该使用
make_unique
函数立即包装每个裸指针,以免任何东西抛出。在C++14中应该有一个
std::make_unique
。它到处都有未定义的行为(更不用说它不会编译)。@James看起来我忘记了两行代码。固定的。还有,好的。不是最简单也不是最理想的,但可以接受。(最简单的方法是只定义一个静态C样式数组,并在其上使用
begin
end
作为
vector
的两个迭代器构造函数的参数)@James这两个解决方案都将元素复制到运行时分配的向量中。如果没有
constepr
'ed
initializer\u list
constructor,我们对此无能为力……正式地说,您的初始化表达式具有未定义的行为<代码>&xv[sizeof(xv)/sizeof(xv[0])]是一种越界访问。实际上,它可能会起作用。但是为什么这么复杂:
std::vector x(std::begin(xv),std::end(xv))<代码>。(当然,您没有C++11,因为否则,您将使用新样式的初始值设定项。因此,事实上,您必须使用工具箱中的std::begin`和
std::end
)的等价物。)@Kanze:No。对于静态分配的数组,允许使用过去最后一个元素的地址(你不能取消对地址的引用,但我没有这么做)。规范中有一个我认为是“bug”,因为动态分配的数组不能保证这一点,而且
(new int[10])+10
确实是正式的UB。但在我的情况下,它是有效的代码。那么
xv[sizeof(xv)/sizeof(xv[0])是什么呢
do?它取消引用结束指针之后的指针。(根据定义,它完全等同于
*(xv+sizeof(xv)/sizeof(xv[0])
)@Kanze:No。表达式不是
xv[sizeof…]
而是
&xv[sizeof…]
。如果
p
是指针,则表达式
&*p
不会取消对指针的引用。有关
int x[10];&x[10];
合法原因的说明,请参阅(包括引用标准)。表达式
xv[sizeof…]有未定义的行为。在未定义的行为之后,您所做的是无关的。C++有一个特殊的规则允许这样做;C++委员会考虑将特殊规则添加到C++中,而不决定。您所引用的答案是错误的。