C++ C++;编译器或链接器优化

C++ C++;编译器或链接器优化,c++,optimization,compiler-construction,linker,autoload,C++,Optimization,Compiler Construction,Linker,Autoload,我正试图使用本文最佳答案中指定的类映射创建一个自动加载类系统: 因此,我根据自己的需要创建了以下代码: // ScriptLoader.h template<class TScript> void createScript() { new TScript; } struct ScriptFactory { public: typedef void(*ScriptCreatorFunc)(); typedef std::map<std::strin

我正试图使用本文最佳答案中指定的类映射创建一个自动加载类系统:

因此,我根据自己的需要创建了以下代码:

// ScriptLoader.h
template<class TScript> void createScript() { 
    new TScript; 
}

struct ScriptFactory {
public:
    typedef void(*ScriptCreatorFunc)();
    typedef std::map<std::string,ScriptCreatorFunc> ScriptCreatorStorage;

    static ScriptCreatorStorage ScriptCreators;

    static bool RegisterCreator(std::string const& s,ScriptCreatorFunc creator)
    {
        ASSERT(ScriptCreators.find(s) == ScriptCreators.end());   // prevent registering the same script twice
        ScriptCreators.insert(std::make_pair(s,creator));
        return true;
    }
};

template<class TScript>
struct ScriptReg : ScriptFactory { 
    ScriptReg(std::string const& s) { 
        ScriptFactory::RegisterCreator(s,&createScript<TScript>);
    }
};

class ScriptLoader {
public:
    static void AddScripts()
    {
        for (ScriptFactory::ScriptCreatorStorage::iterator itr = ScriptFactory::ScriptCreators.begin(); itr != ScriptFactory::ScriptCreators.end(); ++itr)
            itr->second();
    }    
};

#define REGISTER_DEC_TYPE(NAME) \
    static ScriptReg<NAME> reg

#define REGISTER_DEF_TYPE(NAME) \
    ScriptReg<NAME> NAME::reg(#NAME)


// ScriptLoader.cpp
ScriptFactory::ScriptCreatorStorage ScriptFactory::ScriptCreators;

// foo.cpp
class foo:
{
    public:

        foo()
        {
                /* code */
        }

    private:
        REGISTER_DEC_TYPE(foo);
};

REGISTER_DEF_TYPE(foo);
//ScriptLoader.h
模板无效createScript(){
新的TScript;
}
结构脚本工厂{
公众:
typedef void(*ScriptCreatorFunc)();
typedef std::映射脚本创建者存储;
静态脚本创建者存储脚本创建者;
静态bool注册表创建器(std::string const&s,ScriptCreatorFunc creator)
{
断言(ScriptCreators.find)=ScriptCreators.end();//防止两次注册同一脚本
插入(std::make_pair(s,creator));
返回true;
}
};
模板
结构ScriptReg:ScriptFactory{
ScriptReg(std::string const&s){
ScriptFactory::RegisterCreator和createScript;
}
};
类脚本加载器{
公众:
静态void AddScripts()
{
对于(ScriptFactory::ScriptCreatorStorage::迭代器itr=ScriptFactory::ScriptCreators.begin();itr!=ScriptFactory::ScriptCreators.end();++itr)
itr->second();
}    
};
#定义寄存器类型(名称)\
静态脚本注册
#定义寄存器定义类型(名称)\
ScriptReg名称::reg(#名称)
//ScriptLoader.cpp
ScriptFactory::ScriptCreator存储ScriptFactory::ScriptCreators;
//foo.cpp
foo类:
{
公众:
foo()
{
/*代码*/
}
私人:
寄存器类型(foo);
};
寄存器定义类型(foo);
当然,我在一个foo类中定义了REGISTER_DEC_TYPE,并在foo.cpp文件的底部放置了:REGISTER_DEF_TYPE(foo)。。。(AddScripts函数由主程序调用,因此通常以二进制文件链接)

它编译得很好,但当我尝试调试时,我无法在visual studio中设置断点,该断点显示以下提示:“没有与此行关联的可执行代码。可能的原因包括:预处理器指令或编译器/链接器优化”

在foo.cpp中显示:“此文档已加载任何符号”

因此,我猜编译器找不到任何对这些函数/类的“正常”调用,将它们从二进制代码中删除

有没有办法避免这种优化?我正在寻找这个问题的跨平台解决方案


提前感谢

死区剥离是工厂代码的常见问题。你通常需要做的是在某个地方有一个函数,它使用你所有的类型。这很难看,但不幸的是,没有特别优雅的可移植解决方案。

您能准确地解释一下您在代码中的哪一行设置断点吗?RegisterCreator和createScript函数的任何一行,或foo.cpp的foo类中的任何地方(AddScripts函数由主进程调用,因此它通常由编译器链接)你确定你能编译它吗?静态
ScriptReg reg
需要默认的构造函数,但是只有一个构造函数需要
std::string const&s
是的,它编译了,不管怎样,我已经清理了一点代码并编辑了第一篇文章,它继续编译,但还不起作用..foo类和其他代码片段没有在二进制文件中链接。它也是如此需要调用主进程中某个地方的所有类才能在map中注册?大多数编译器都会删除未使用的符号(死区剥离)这样,您的可执行文件中就不会出现未使用的积垢。不幸的是,在这种情况下,它过于热情,因此,是的,您需要使用它们。在一个中央
register
函数中进行所有register调用将实现这一点。