您的代码存在一些问题,我将展示其中的一些问题,不分先后。
(1) 在结构/类中不允许完全的特化;所以你不能完全专注于log2 内部log2arr。
您可以将log2 迁移到log2arr 之外,或者,如果您真的想在log2arr 内部维护它,您可以将完全专业化转换为等效的部分专业化(在结构/类中合法);举例如下
template <int I, typename = std::true_type>
struct log2
{
// body of the struct
};
template <int I>
struct log2<I, std::integral_constant<bool, I == 1>>
{
// body of the struct specialization
};
(2) 如果你从getArr() 返回一个int *,你会丢失log2Arr 类中关于数组的信息;所以不适用于基于范围的 for 循环 (for(auto i : a.getArr()))。
很遗憾,您无法返回 C 样式的数组(您无法返回 arr 本身)。
但是您使用的是 C++11 或更新版本(您只标记了 C++,但您使用的是基于范围的 for 循环,因此您至少使用的是 C++11)所以我强烈建议您定义 @987654332 @ 作为 std::array<int, N>,而不是 C 样式数组(不是 int arr[N])。我强烈建议您返回对arr 本身的引用(使用std::array 可以做到)
private:
using arrT = std::array<int, N>;
arrT arr {};
// ...
public:
arrT & getArr ()
{ /* ... */ return arr; }
我还建议为const 对象添加getArr()
arrT const & getArr () const
{ /* ... */ return arr; }
(3) 您无法在嵌入结构log2 的方法中管理arr 数组(不是log2Arr 的静态成员)
void set()
{
_arr.set();
arr[i] = value; // <--- arr is inaccessible
}
一个可能的解决方案是传递arr 作为参考,所以
void set (arrT & a) // arrT = std::array<int, N>
{
_arr.set(a);
a[i] = value;
}
和(在log2<1>)
void set (arrT &) {}
显然你必须调用set() 传递arr 作为参数,所以
log2<N>().set(arr)
(4) 在getArr() 中初始化arr 是个坏主意(恕我直言),因为每次调用getArr() 时都会初始化arr。
此外:你不能在另一个方法中使用arr(如果你想添加另一个)而不在另一个方法中初始化它。
建议:在显式构造函数中初始化arr,一劳永逸;举例
log2arr ()
{ log2<N>().set(arr); }
所以你的 getArr() 方法就变成了
arrT & getArr ()
{ return arr; }
arrT const & getArr () const
{ return arr; }
(5) 使用 log2<I> 初始化 arr[I] 和 log<1> 未初始化任何内容,您的 int arr[N] 包含未初始化的 arr[0] 和 arr[1] 值。
您可以将这些值初始化为零写入
int arr[N] {};
或(使用std::array<int, N>)
using arrT = std::array<int, N>;
arrT arr {};
// ^^ <--- initialize all to zero
但您必须决定如何在arr[0] 和arr[1] 中初始化
(6) 不需要像下面这样初始化a
log2arr<4> a = log2arr<4>();
你可以简单地写
log2arr<4> a;
---------------------------------------
以下是修改后的代码
#include <array>
#include <iostream>
template <int I>
struct power2
{ enum { value = (1 << I) }; };
template <int N>
class log2arr
{
private:
using arrT = std::array<int, N>;
arrT arr {};
template <int I, typename = std::true_type>
struct log2
{
log2<I-1> _arr;
enum { value = log2<I-1>::value
+ (power2<log2<I-1>::value>::value == I) };
void print ()
{ _arr.print(); std::cout << value << std::endl; }
void set (arrT & a)
{ _arr.set(a); a[I] = value; }
};
template <int I>
struct log2<I, std::integral_constant<bool, I == 1>>
{
enum { value = 1 };
void print() {}
void set(arrT &) {}
};
public:
log2arr ()
{ log2<N>().set(arr); }
arrT & getArr ()
{ return arr; }
arrT const & getArr () const
{ return arr; }
};
int main ()
{
log2arr<4> a;
for ( auto i : a.getArr() )
std::cout << i;
std::cout << std::endl;
}