roz*_*ina 11 c++ arrays static constexpr
是否有可能在C++中有这样的东西:
struct Foo
{
int x;
constexpr Foo(int x) : x(x) {}
static constexpr Foo table[] =
{
Foo(0),
Foo(1),
Foo(2),
};
};
Run Code Online (Sandbox Code Playgroud)
我尝试了几种组合,但都没有效果.如果table不是Foo类的一部分,它可以工作,但我真的希望它成为Foo命名空间的一部分.
编辑:
我想要这个的原因是我可以访问表格Foo::table.我在命名空间中有几个这样的类,如果我可以通过编写导入我正在使用的类using someNamespace::Foo然后访问该表,这非常方便Foo::table.如果表在课外,我必须始终通过写作来访问它someNamespace::fooTable.
error: invalid use of incomplete type 'struct Foo'
Foo(0),
^
note: definition of 'struct Foo' is not complete until the closing brace
struct Foo
^~~
Run Code Online (Sandbox Code Playgroud)
Foo被认为是"不完整类型",直到达到其定义的右大括号.不完整类型的大小是未知的,因此编译器不知道需要多少空间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];
}
Run Code Online (Sandbox Code Playgroud)
用法:
int main()
{
constexpr auto x = Foo::table[1];
}
Run Code Online (Sandbox Code Playgroud)
如果您不想Foo复制,可以table在"详细信息"中放置namespace,然后const auto&从FooTable::operator[]- 示例返回此处.
您可以使用以下技巧,它基本上将表移动到模板化包装器,只有在类定义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 Code Online (Sandbox Code Playgroud)
在您的情况下,不确定这是否真的是一种可接受的解决方法,但它是如何让您的示例编译和运行的.
如果要在类中指定表条目的初始化值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) {}
};
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您都可以从中派生所有类,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) {}
};
Run Code Online (Sandbox Code Playgroud)
也可以实现向每个构造函数传递多个参数.std::pair在这种情况下,使用一个或其他包装器对它们进行分组.
| 归档时间: |
|
| 查看次数: |
430 次 |
| 最近记录: |