Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 本地静态对象的非延迟初始化?_C++_Static_Static Initialization - Fatal编程技术网

C++ 本地静态对象的非延迟初始化?

C++ 本地静态对象的非延迟初始化?,c++,static,static-initialization,C++,Static,Static Initialization,gcc(4.8)或icc(14.0)是否有任何模式或其他非标准机制可以保证静态局部变量的早期安全构建 我需要一个本地静态对象引用的全局集合,以便在运行时进行粗略分析。标准的延迟构造(以及处理锁定或冗余的本地集合)会让我深受伤害,在开始时拥有完整的点列表将是非常有利的 有希望实现这一点吗 #include <iostream> #include <deque> // Really want to build this list before main() started!

gcc(4.8)或icc(14.0)是否有任何模式或其他非标准机制可以保证静态局部变量的早期安全构建

我需要一个本地静态对象引用的全局集合,以便在运行时进行粗略分析。标准的延迟构造(以及处理锁定或冗余的本地集合)会让我深受伤害,在开始时拥有完整的点列表将是非常有利的

有希望实现这一点吗

#include <iostream>
#include <deque>

// Really want to build this list before main() started!
struct ProfilePoint;
static std::deque<ProfilePoint *> pps;

// Costly construction, but only ever with literal/constexpr params.
// Templating, etc., also discourages non-local building in reality.
struct ProfilePoint {
  ProfilePoint(int id, char const *i) : id_(id), inf_(i) { pps.push_back(this); }
  void doStuff() { /* ... */ }
  int id_;
  char const *const inf_;
};

// Functions like this will be called concurrently in reality.
void bar(int cnt) {
  for (int i = 0; i < cnt; ++i) {
    // Dropping in a local definition/call should be enough to hook in to system
    static ProfilePoint pp(2, "description in a string literal");
    pp.doStuff();
    /* ... */
  }
}

void dump() {
  std::cout << "[";
  for (ProfilePoint *pp: pps) { std::cout << " " << pp->id_ << ":" << pp->inf_; }
  std::cout << " ]" << std::endl;
}

int main() { dump(); bar(5); dump(); } // "[ ]" then "[ 2 ]" in gcc/icc
还请注意,对集合使用Meyers singleton方法完成了此方法的总体安全性。但是,可能必须锁定集合以防止并发的点静态初始化。我仍然需要检查规范以确认此规范,以及是否在main()之前强制执行静态成员初始化。

试试这个

#include <iostream>
#include <deque>

// Really want to build this list before main() started!
struct ProfilePoint;
static std::deque<ProfilePoint *> pps;

// Costly construction, but only ever with literal/constexpr params.
// Templating, etc., also discourages non-local building in reality.
struct ProfilePoint {
  ProfilePoint(int id, char const *i) : id_(id), inf_(i) { pps.push_back(this); }
  void doStuff() { /* ... */ }
  int id_;
  char const *const inf_;
};

template<class IdDescription>
struct ProfilePoint_{
  static ProfilePoint p;


};

template<class IdDescription>
ProfilePoint ProfilePoint_<IdDescription>::p( IdDescription::id(),    IdDescription::description() );

#define PROFILE_POINT(theid,thedescription) \
struct ppdef_static_class{ \
  static int id(){ return theid; } \
  static const char* description(){ return thedescription; } \
  };\
  static ProfilePoint_<ppdef_static_class>

// Functions like this will be called concurrently in reality.
void bar(int cnt) {
  for (int i = 0; i < cnt; ++i) {
    // Dropping in a local definition/call should be enough to hook in to system
    PROFILE_POINT(2, "description is a string literal") pp;

    pp.p.doStuff();
    /* ... */
 }
}

void dump() {
  std::cout << "[";
  for (ProfilePoint *pp : pps) { std::cout << " " << pp->id_ << ":" << pp->inf_; }
  std::cout << " ]" << std::endl;
}

int main() { dump(); bar(5); dump(); } // Does what you want
#包括
#包括
//真的想在main()启动之前构建此列表!
结构轮廓点;
静态标准:deque pps;
//昂贵的构造,但仅使用literal/constexpr参数。
//模板等,也不鼓励非本地建筑在现实中。
结构轮廓点{
ProfilePoint(int-id,char-const*i):id(id),inf(i){pps.push_-back(this);}
void doStuff(){/*…*/}
int-id_2;;
字符常量*常量inf;
};
模板
结构轮廓点_{
静态剖面点p;
};
模板
ProfilePoint ProfilePoint_uuP(IdDescription::id(),IdDescription::description());
#定义轮廓点(ID,描述)\
结构ppdef_静态_类{\
静态int-id(){return theid;}\
静态常量char*description(){返回描述;}\
};\
静态轮廓点_
//这样的函数在现实中将被同时调用。
空心条(内部cnt){
对于(int i=0;i
#include <iostream>
#include <deque>
#include <memory>
#include <map>

class ProfilePoint
{
    public:
    typedef unsigned Identifier;

    private:
    struct Data {
        Identifier id;
        const char* information;
        unsigned count;

        Data(Identifier id, const char* information)
        :   id(id), information(information), count(0)
        {}
    };

    public:
    static void dump();

    const char* information() const { return m_data.information; }
    Identifier id() const { return m_data.id; }

    ProfilePoint(const char* information)
    :   m_data(*get_data(0, information))
    {}

    void apply() const {
        ++m_data.count;
    }

    private:
    static Data* get_data(Identifier, const char* information);
    Data& m_data;
};


ProfilePoint::Data* ProfilePoint::get_data(Identifier id, const char* information) {
    typedef std::deque<Data> StaticData;
    StaticData static_data;
    if( ! information) return &static_data[id];
    else {
        static_data.push_back(Data(static_data.size(), information));
        for(auto d: static_data)
            std::cout << d.information << std::endl;
        return &static_data.back();
    }
    return 0;
}

void ProfilePoint::dump() {
    std::cout << "dump" << std::endl;
    Data* data;
    for(Identifier i = 0; (data = get_data(i, 0)); ++i) {
        std::cout
            << "Profile Point: " << data->information
            << ", Count: " << data->count << std::endl;
    }
}


namespace {

ProfilePoint pf("Function");
void f() {
    pf.apply();
    pf.apply();
    pf.apply();
    ProfilePoint::dump();

}

} // namespace

int main()
{
    f();
    return 0;
}
#包括
#包括
#包括
#包括
类轮廓点
{
公众:
typedef无符号标识符;
私人:
结构数据{
标识符id;
常量字符*信息;
无符号计数;
数据(标识符id、常量字符*信息)
:id(id)、信息(information)、计数(0)
{}
};
公众:
静态空转储();
const char*information()const{return m_data.information;}
标识符id()常量{return m_data.id;}
ProfilePoint(常量字符*信息)
:m_数据(*获取_数据(0,信息))
{}
void apply()常量{
++m_data.count;
}
私人:
静态数据*获取数据(标识符、常量字符*信息);
数据&m_数据;
};
ProfilePoint::Data*ProfilePoint::获取_数据(标识符id、常量字符*信息){
typedef std::deque StaticData;
静态数据静态数据;
如果(!信息)返回和静态_数据[id];
否则{
static_data.push_back(数据(static_data.size(),信息));
用于(自动d:静态_数据)

std::这在我的编译器上也能起作用,但我有点不知道为什么。我有什么保证,我的静态数据将首先从一个可能不同的编译单元初始化,是什么使得模板实例化足够特殊,从而强制在那里进行静态初始化?感谢您提出这种方法ch!@Jeff关于pps没有任何保证。要获得保证,请使用Meyers单例技巧
std::deque&pps(){static std::deque d;return d;}
并用
pps()替换
pps.
)杰夫,关于它为什么工作,在函数中定义一个静态成员的类。C++标准保证类静态成员在启动时初始化,不像函数第一次初始化的函数静态变量。哦,Duh。我只是假设本地类遵循本地静态对象初始化。这说明,上面提到的1 pp/作用域的简单限制是什么?将实例名传递到宏中以生成唯一的ppdef_static_class_XXX name?@Jeff只要函数中的id是唯一的,就将id名附加到宏中的类中。类似于
ppdef_static_class#theid
#include <iostream>
#include <deque>
#include <memory>
#include <map>

class ProfilePoint
{
    public:
    typedef unsigned Identifier;

    private:
    struct Data {
        Identifier id;
        const char* information;
        unsigned count;

        Data(Identifier id, const char* information)
        :   id(id), information(information), count(0)
        {}
    };

    public:
    static void dump();

    const char* information() const { return m_data.information; }
    Identifier id() const { return m_data.id; }

    ProfilePoint(const char* information)
    :   m_data(*get_data(0, information))
    {}

    void apply() const {
        ++m_data.count;
    }

    private:
    static Data* get_data(Identifier, const char* information);
    Data& m_data;
};


ProfilePoint::Data* ProfilePoint::get_data(Identifier id, const char* information) {
    typedef std::deque<Data> StaticData;
    StaticData static_data;
    if( ! information) return &static_data[id];
    else {
        static_data.push_back(Data(static_data.size(), information));
        for(auto d: static_data)
            std::cout << d.information << std::endl;
        return &static_data.back();
    }
    return 0;
}

void ProfilePoint::dump() {
    std::cout << "dump" << std::endl;
    Data* data;
    for(Identifier i = 0; (data = get_data(i, 0)); ++i) {
        std::cout
            << "Profile Point: " << data->information
            << ", Count: " << data->count << std::endl;
    }
}


namespace {

ProfilePoint pf("Function");
void f() {
    pf.apply();
    pf.apply();
    pf.apply();
    ProfilePoint::dump();

}

} // namespace

int main()
{
    f();
    return 0;
}