考虑:
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
将不再是聚合,因此上述语法无效。
在这种情况下,是否可以通过编程方式恢复此行为?
答案 0 :(得分:0)
聚合初始化仅适用于聚合,因此严格来说,这是不可能的。
您可以通过提供initializer_list / variadic模板构造函数或通过构造函数来模拟它,只为初始化目的而采用张量数据结构的聚合版本,例如:
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 []的链接(因此你需要嵌套数据为Tensor类型),它仍然可能,但需要一个不那么简单的初始化逻辑。