如果我想使用像make_array
这样的便利之类的东西,我没有机会先声明我的数组,然后在"之前的#34;中完成定义。时间因为我的var的类型在定义之前不可用。
所以我找到了这个答案:
Undefined reference to static constexpr char[]
在下面的例子中,我写了这个用gcc编译好的解决方案,我不确定这是非常有效的c ++代码,因为它或多或少是一个带有定义的声明,后来是一个没有任何内容的定义。这是允许的吗? (编译罚款不能保证代码有效c ++)
#include <experimental/array>
#include <iostream>
class Foo
{
private:
static decltype(auto) constexpr Bar =
std::experimental::make_array(
std::experimental::make_array( 1,2,3 ),
std::experimental::make_array( 4,5,6 )
);
public:
using ARR_TYPE = decltype( Bar );
static auto& GetArr( int idx )
{
// range check ...
return Bar[idx];
}
};
constexpr Foo::ARR_TYPE Foo::Bar;
int main()
{
for ( auto el: Foo::GetArr(0))
{
std::cout << el << std::endl;
}
}
答案 0 :(得分:4)
管理static constexpr
成员的规则在C ++ 1z中发生了变化,这有点令人讨厌。
[...]文字类型的静态数据成员可以使用constexpr说明符在类定义中声明;如果是这样,它的声明应指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [...] 如果程序中使用了odr-used ([basic.def.odr]),则成员仍应在命名空间范围内定义,并且命名空间范围定义不应包含初始化程序
这意味着您必需在声明中提供初始值设定项,但也提供命名空间范围的定义,而无需初始值设定项。
您的代码正是如此。
来自同一段[class.static.data]
[...]如果使用constexpr说明符声明成员,则可以在没有初始值设定项的命名空间范围内重新声明(不推荐使用此用法;请参阅[depr.static_constexpr])。 [...]
为了与先前的C ++国际标准兼容,constexpr静态数据成员可以在课外冗余重新声明而不使用初始化程序。不推荐使用此用法。
所以,这仍然是合法的,但已被弃用。
应该注意static
但是constexpr
成员(包括static const
成员)仍然需要在命名空间范围内有一个定义,如果它是使用过的。