模拟递归定义的类似数组类的聚合初始化
Emulate aggregate initialization for recursively-defined array-like class
考虑:
template <std::size_t r,std::size_t d>
struct Tensor
{
Tensor<r-1u,d> Data[d];
};
template <std::size_t d>
struct Tensor<0u,d>
{
double Data;
};
我们可以使用 copy-list-initialization 来初始化这样的Tensor
:
Tensor<2u,3u> t= { 1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0 };
注意大括号省略。
这也适用于通用编程上下文,例如:
template <typename... T,
typename= std::enable_if_t<(std::is_same_v<T,double> && ...) && (sizeof...(T)==9u)>>
Tensor<2u,3u> MakeTensor(T... x) { return {x...}; }
但是,如果Data
是私有的,则Tensor
将不再是聚合,因此,上述语法将无效。
在这种情况下,是否可以以编程方式恢复此行为?
聚合初始化仅适用于聚合,所以不,严格来说,这是不可能的。
您可以通过提供 initializer_list/可变参数模板构造函数或通过构造函数来模拟它,该构造函数仅出于初始化目的获取张量数据结构的聚合版本,如下所示:
template <std::size_t r,std::size_t d>
struct RawTensor
{
std::array<RawTensor<r-1u,d>,d> data;
};
template <std::size_t d>
struct RawTensor<0u,d>
{
double data;
};
template <std::size_t r,std::size_t d>
struct Tensor
{
Tensor( RawTensor<r,d> const& data ): data_{data}{}
private:
RawTensor<r,d> data_;
};
template <typename... T,
typename= std::enable_if_t<(std::is_same_v<T,double> && ...) && (sizeof...(T)==9u)>>
RawTensor<2u,3u> MakeTensor(T... x) { return {x...}; }
Tensor<2u,3u> t1 = RawTensor<2u,3u>{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
Tensor<2u,3u> t2 = MakeTensor( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 );
并让编译器对其进行优化。如果你的初衷是利用 operator[] 的链接(因此你需要嵌套数据是张量类型),它仍然是可能的,但需要一个不那么简单的初始化逻辑。
相关文章:
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在函数内部的声明中初始化数组,并在外部使用它
- 为什么用结构初始化数组需要指定结构名称
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++使用另一个数组和新值初始化数组
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 在 constexpr 构造函数中初始化数组是否合法?
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在构造函数中初始化数组
- 是否可以使用函数返回的值初始化数组
- 使用宏使用额外元素初始化数组
- 在循环中显示不同值的初始化数组
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 使用可变模板列表初始化数组,并放置new
- 使用函数从 Visual Studio 2017 中的 main 创建和初始化数组
- 使用 c++ 中的函数初始化数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- C++ 使用变量而不是常量表达式初始化数组
- 在初始化列表中初始化数组的更好方法
- 在可变参数模板类中初始化数组