所以我读了这篇关于使用静态初始化来注册类(http://quantumgraphics.blogspot.nl/2014/11/abusing-static-initialization.html)的文章。这正是我所需要的,所以我决定实施它。然而,我无法让它工作,所以我做了一个小测试案例,以确保我得到了正确的细节。事实证明,即使是一个简单的例子也不起作用(http://ideone.com/HDr8ZM):
#include <iostream>
int a = 0;
template<
class T
>
class Scriptable {
protected:
struct Proxy
{
Proxy() {
std::cout << "Proxy was executed! ID: " << T::id << std::endl;
a++;
}
};
static Proxy proxy_;
} ;
template<
class T
>
typename Scriptable<T>::Proxy Scriptable<T>::proxy_;
class Object : public Scriptable<Object> {
public:
constexpr static auto id = "[Object]";
} ;
int main() {
std::cout << "Done " << a << std::endl;
}
所以基本上需要发生的事情(或者更确切地说,我想要发生的事情)是代理构造函数应该在main之前执行。我想使用Proxy构造函数向一些单例基类工厂注册该类,但我不认为与此代码相关的代码无效。
有人能指出我正确的方向吗?我可能错过了编译器标志或其他东西(该示例应仅使用-std = c ++ 11标志进行编译)。或者是否有更好的方法来做我在这里尝试的事情?
非常感谢任何帮助!
答案 0 :(得分:2)
通过Pradhan的链接,我能够做出我需要的东西:
#include <iostream>
int a = 0;
template <typename T, T /*unnamed*/>
struct nnb_ForceInit { };
template<
class T
>
class Scriptable {
public:
struct nnb_Proxy {
nnb_Proxy() {
std::cout << "Proxy was executed! ID: " << T::id << std::endl;
a++;
}
};
static nnb_Proxy __nnb_proxy__;
typedef nnb_ForceInit<nnb_Proxy&, __nnb_proxy__> __nnb_typedef_dummy__;
} ;
template<
class T
>
typename Scriptable<T>::nnb_Proxy Scriptable<T>::__nnb_proxy__;
class Object : public Scriptable<Object> {
public:
constexpr static auto id = "[Object]";
};
class Image : public Scriptable<Image> {
public:
constexpr static auto id = "[Image]";
};
class Error : public Scriptable<Error> {
public:
constexpr static auto id = "[Error]";
} ;
int main() {
std::cout << "Done " << a << std::endl;
}
我不清楚它是如何正常工作的,但似乎做了我想要/工作得很好的事情,所以我想这就是它。
答案 1 :(得分:1)
它没有用,因为你的Proxy
没有理由构建。在这种情况下,您的main()
甚至无法构建Object
- 那么为什么Proxy
会被构建?你必须至少这样做:
int main() {
Object o;
std::cout << "Done " << a << std::endl;
}
但是,简单地构建o
并不以任何方式引用代理,因此仍然没有理由构造代理。你不得不以某种方式触摸它。最简单的方法是在Scriptable
的构造函数中引用它:
Scriptable() {
proxy_; // this line throws a warning, since this line does nothing,
// so replace it with something reasonable. but this line is
// enough to force proxy_ to be instantiated.
}
如果我添加这两位(Object o;
和Scriptable
构造函数),那么您的代码会产生:
Proxy was executed! ID: [Object]
Done 1
另一种方法是在构造函数中实际声明proxy_
:
Scriptable() {
static Proxy proxy_;
}