静态constexpr成员变量初始化

13

我有以下代码:

struct Foo
{       
    struct Bar
    {
        std::uint32_t x = -1;

        constexpr Bar(std::uint32_t x) : x(x) {}
    };

    static constexpr Bar CONST_BAR = Bar(0);
};

当我尝试编译它时,我会得到以下错误:

错误:在常量表达式中,在其定义完成之前调用‘constexpr Foo::Bar::Bar(uint32_t)’

有人可以解释一下发生了什么吗?就我所看到的,Bar的构造函数在第一个调用之前已经被定义了。

实例链接


引用@evg链接中的答案:“通常情况下,类成员在声明它们的类完成之前不被认为已经声明。” - einpoklum
1
这本质上是Evg链接到的相同问题。在Bar的构造函数内部,应该将Foo视为完整的(https://timsong-cpp.github.io/cppwp/n4140/class#mem-2)。这意味着它(虽然间接地)依赖于`Foo`的完整性才能在常量表达式中使用。因此,在`Foo`尚未完整之前,它不能用于上下文中。 - StoryTeller - Unslander Monica
很不幸。感谢您找到了解释。 - rozina
2个回答

2

我没有详细的解释,但我也遇到了这个问题,认为它至少值得一提... 除了将CONST_BAR的定义放在Foo结构体之外,另一个可能的解决方法是实例化Foo

// Example program
#include <iostream>
#include <string>

template<typename T = void>
struct Foo
{       
    struct Bar
    {
        std::uint32_t x = -1;
    
        constexpr Bar(std::uint32_t x) : x(x) {}
    };
    
    static constexpr Bar CONST_BAR = Bar(0);
};

int main()
{
    std::cout << "x: " << Foo<>::CONST_BAR.x << "\n";
}

0
你可能想尝试像这样初始化 -
static constexpr Foo::Bar CONST_BAR = Foo::Bar(0);

因为结构体foo的声明必须完成,所以在结构体Foo之外。


然后,声明的变量将位于不同的作用域(全局而不是 foo)。 - JHBonarius
2
是的,因此它不同,也不是一个解决方案。 - JHBonarius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接