【问题标题】:Template, Inheritance, static member incrementation模板、继承、静态成员递增
【发布时间】:2019-07-06 12:14:36
【问题描述】:

以下代码在我看来应该输出sum sizeof(int) + sizeof(float) + sizeof(std::string),但存储值始终为零。为什么?

struct Base {
    static int IncrementID(int x) {
        static int id = 0;
        storage += x;
        return id++;
    }
    static int storage;
};
int Base::storage = 0;

template<typename T>
struct Object : public Base {
    static const int id;
};
template<typename T>
const int Object<T>::id(Base::IncrementID(sizeof(T)));

int main() {
    Object<int> a;
    Object<float> b;
    Object<std::string> c;

    std::cout << Base::storage;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    您不要以任何可能导致其隐式实例化的方式使用这些静态 id 数据成员。这意味着它们不必被实例化(也不必进行初始化)。引用 C++ 标准:

    [temp.inst]

    3 除非类模板的成员或成员模板有 被显式实例化或显式特化, 成员的特化被隐式实例化,当 在需要成员的上下文中引用专业化 存在的定义;特别是,初始化(和任何 静态数据成员的相关副作用)不会发生,除非 静态数据成员本身的使用方式需要 要存在的静态数据成员的定义。

    做一些简单的事情,比如添加一个用户定义的构造函数,比如

    Object() {
        int i = id;
        (void)i;
    }
    

    Can be enough odr 使用它们,并像你一样通过创建对象来强制实例化它们。

    【讨论】:

    • 顺便说一句,如果 C++17 可用 static inline 也可以。
    • @DeiDei - 当我尝试它的coliru.stacked-crooked.com/a/101b9717c7db71b4时似乎没有这样做@
    • 哦,我只用 MSVC 15.9.13 测试过。猜猜那是什么。
    猜你喜欢
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 2013-05-09
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2014-10-08
    相关资源
    最近更新 更多