静态constexpr数组类本身
内是否有可能有这样的事情在C++:静态constexpr数组类本身
struct Foo
{
int x;
constexpr Foo(int x) : x(x) {}
static constexpr Foo table[] =
{
Foo(0),
Foo(1),
Foo(2),
};
};
我尝试了好几种组合,但没有工作。如果table不是Foo类的一部分,它会起作用,但是我真的很喜欢它成为Foo命名空间的一部分。
编辑:
我想是这样的话,我可以访问该表为Foo::table
原因。我有几类这样的命名空间,这是真的很方便,如果我可以通过写using someNamespace::Foo
导入我使用的类,然后访问该表为Foo::table
。如果表格在课程之外,我必须通过编写someNamespace::fooTable
来访问它。
的compiler error is clear here:
error: invalid use of incomplete type 'struct Foo'
Foo(0),
^
note: definition of 'struct Foo' is not complete until the closing brace
struct Foo
^~~
Foo
被认为是"incomplete type",直至达到其定义的右大括号。不完全类型的大小是不知道的,所以编译器不知道有多少空间table
需要。
这里有一个解决方法:
struct FooTable
{
constexpr auto operator[](int n) const;
};
struct Foo
{
int x;
constexpr Foo(int x) : x(x) {}
constexpr static FooTable table{};
};
constexpr auto FooTable::operator[](int n) const
{
constexpr Foo table[] =
{
Foo(0),
Foo(1),
Foo(2),
};
return table[n];
}
用法:
int main()
{
constexpr auto x = Foo::table[1];
}
如果你不想Foo
被复制,则可以将table
内“详细信息“namespace
,然后返回const auto&
从FooTable::operator[]
- example here。
您可以使用下面的技巧,基本上出招表的模板化的包装,这是只有在实例化时的Foo
类定义完成。
template<typename T>
struct Wrapper
{
static constexpr T table[] = { T(0), T(1), T(2) };
};
struct Foo : public Wrapper<Foo>
{
int x;
constexpr Foo(int x) : x(x) {}
};
不知道这是否实际上是在您的情况可以接受的解决办法,但它是你如何能得到你的榜样编译和run。
如果你想在Foo
类中指定表项的初始值,可以延长包装采取这些值:
template<typename T, int... Args>
struct Wrapper
{
static constexpr T table[] = { T(Args)... };
};
struct Foo : public Wrapper<Foo, 0, 1, 2>
{
int x;
constexpr Foo(int x) : x(x) {}
};
在这两种情况下,你可以把所有的类都是从Wrapper
派生而不需要定义更多的实例,因为每个实例化都存在静态的Wrapper
。如果您需要输入采取比其他int
值,你也可以通过这种类型的另一个模板参数:
template<typename T, typename A, A... Args>
struct Wrapper
{
static constexpr T table[] = { T(Args)... };
};
struct Foo : public Wrapper<Foo, int, 0, 1, 2>
{
int x;
constexpr Foo(int x) : x(x) {}
};
struct Bar : public Wrapper<Bar, char, 'a', 'b', 'c'>
{
char x;
constexpr Bar(char x) : x(x) {}
};
传递多个参数到每个构造函数是可以实现的,以及。在这种情况下,使用std::pair
或其他包装将它们分组。
@ tobi303不,因为表格是静态的。 – rozina
对不起,忽略了那个 – user463035818
它不能工作,因为当解析'table'时,你没有'Foo'的完整定义。要创建一个'Foo'的实例,你需要完整的定义,编译器必须解析整个结构直到结束。 –