为每个C++类模板实例执行一次代码

Sil*_*cer 5 c++ templates class-template c++11

好的,这是一个复杂的问题.

我有一个多次实例化的C++类模板.对于这些实例中的每一个,我都需要执行一个注册一些运算符的函数.这需要该模板实例中使用的第一目标(这并不意味着它必须在执行前每个模板实例只需进行一次在 instanciation这在编译时有发生).

最新的我手动完成了这个.但这是一种痛苦.所以我想自动执行注册功能.

我目前的想法是在构造函数中调用一个受保护的注册方法.然而,每当构造一个类的实例时,这需要(小的)开销.由于这种情况经常发生,我想避免这种开销.

我还尝试使用静态RAII帮助程序成员,但如果没有主动访问静态模板类成员,则不会构造静态模板类成员,因此尝试失败.

有没有办法在类模板instanciation上执行代码(通过函数或可能由RAII帮助程序类)而没有运行时开销?

Ant*_*vin 6

您可以添加一个静态数据成员,该成员将执行其构造函数和析构函数中所需的任何内容.您可以放心地将其定义放入头文件中,因为只要它是模板,它就只定义一次.唯一的问题是要实例化它,你必须使用它.

template <typename T>
class Data {
public:
    Data() {
        std::cout << "creating Data<" << typeid(T).name() << '>' << std::endl;
    }
    ~Data() {
        std::cout << "destroying Data<" << typeid(T).name() << '>' << std::endl;
    }
};

template<typename T>
class A {
    static Data<T> data;
public:
    A() {
        // this is necessary for data to be instantiated
        (void)data;
    }
 };

// This also should be in a header
template<typename T>
Data<T> A<T>::data;

int main(){
    A<int> aInt;
    A<int> aInt2;
    A<float> aFloat;
}
Run Code Online (Sandbox Code Playgroud)

演示

编辑:这实际上有点不安全,因为在不同的翻译单元中创建静态对象的顺序是未指定的,因此例如std::cout在exetucion时可能没有Data::Data()(因此不要在那里使用任何静态全局对象).更安全的方法是调用静态函数A::A(),但它会引入一些开销:

template<typename T>
class A {
    static void createData() {
        static Data<T> data;
    }
public:
    A() {
        createData();
    }
};
Run Code Online (Sandbox Code Playgroud)