c++ - 在结构中初始化静态 constexpr 变量和类

标签 c++ struct constexpr

这是我的工作代码示例:

#include <iostream>

template<typename B>
class b {
public:
    int y;

    constexpr b(int x) : y(x) {

    }

    constexpr void sayhi() {
        std::cout << "hi" << std::endl;
    }
};



template<int x>
struct A {
    static constexpr b<int> bee = x;
    static constexpr int y = x;         // this one is fine and usable already, I don't have to do something like what I did on member bee

    inline static void sayhi() {
        std::cout << y << std::endl;
    }
};

template<int x>
constexpr b<int> A<x>::bee;        // why do I have to do something like this, it will cause errors if I don't.

int main(int argc, char** argv) {
    A<30>::bee.sayhi();             // works fine
    A<30>::sayhi();                 // works fine

    return 0;
}

我的代码做的很简单,我有模板结构 A有两个静态变量,即 static constexpr int y和一个 static constexpr b<int> bee = x; .我的模板结构 A将获得将由 x 复制的参数值从模板参数。我的问题是:为什么说到类,我必须通过执行以下操作来初始化类:

template<int x>
constexpr b<int> A<x>::bee; 

如果我不使用上面的代码,我会得到 undefined引用错误。其中 int 已经很好并且可以通过执行以下操作访问:

static constexpr int y = x;    

我担心为什么我不必再转发声明它了。

最佳答案

static constexpr 成员在 class { } 范围内初始化时有一个值,但它在内存中没有位置(地址)直到它被在 class { } 之外定义。原因是您可能决定将其部分或全部特化包含在链接库中(例如 .o.so),或者是否提供有效的内联链接默认情况下到特化。

如果曾经使用过对象的地址,则需要类外定义,这意味着它必须作为全局变量存在。另一方面,如果您希望 constexpr 成员仅在编译时存在,禁止全局存储分配,那么省略定义是一个不错的选择。

顺便说一句,不允许将 constexpr 说明符放在永远不能作为常量表达式求值的函数上,例如打印到 sayhi >std::cout。这是“无需诊断 (NDR)”规则,意味着编译器现在可能不会提示,但下一个编译器版本可能会提示。

关于c++ - 在结构中初始化静态 constexpr 变量和类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31531273/

相关文章:

c++ - Qt:强制QWebView点击一个网络元素,即使是在窗口上不可见的元素

c++ - 是否有用于指针删除的功能(对象)模板可在某处(增强,STL)重用?

c++ - 如何将结构从C++传递给C?

c - C 中的结构 x 与 x_t

mongodb - 使用 'reflect' 将数据 append 到指向已定义结构的接口(interface)

c++ - 关于指针值是编译时常量的困惑

c++ - 有条件的 constexpr 成员函数

c++ - 模块机器类型 'THUMB' 与目标机器类型 'ARM' 冲突

c - 如何在c中创建嵌套结构

c++ - 带有 constexpr 函数失败的模板实例化