gpt4 book ai didi

c++ - 使用元编程计算log2但是 `compilation terminated`

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:19 24 4
gpt4 key购买 nike

我是 TMP 的新手,我使用元编程编写了一个程序来计算 log2。我写了一个模板结构 power2 来计算幂,一个模板类 log2arr 里面有一个数组来保存结果,还有一个嵌入式模板结构 log2 计算 log2 值。

#include <iostream>

template <int i>
struct power2
{
enum
{
value = (1 << i)
};
};

template <int n>
class log2arr
{
int arr[n];

template <int i>
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()
{
_arr.set();
arr[i] = value;
}
};

template <>
struct log2<1>
{
enum
{
value = 1
};
void print() {}
void set() {}
};

public:
int *getArr()
{
log2<n>().set();
return arr;
}
};

int main()
{
log2arr<4> a = log2arr<4>();
for(auto i : a.getArr()){
cout << i;
}
}

但编译器只告诉我编译终止。

这是什么意思?我该如何解决?

如有任何帮助,我们将不胜感激。

最佳答案

您的代码有一些问题,我将展示其中的一些问题,排名不分先后。

(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) 如果你从 int * 返回一个 getArr() ,你丢失了关于 log2Arr 类中数组的信息;所以不适用于基于范围的 for 循环 ( for(auto i : a.getArr()) )。

不幸的是,您不能返回 C 风格的数组(您不能返回 arr 本身)。

但是你使用的是 C++11 或更新版本(你只标记了 C++ 但你使用的是基于范围的 for 循环,所以你至少使用了 C++11)所以我强烈建议你将 arr 定义为一个 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; }

我还建议为 getArr() 个对象添加一个 const

  arrT const & getArr () const
{ /* ... */ return arr; }

(3) 您不能在嵌入式结构 arr 的方法中管理 log2Arr 数组(不是 log2 的静态成员)

    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) 在 arr 中初始化 getArr() 是个坏主意(恕我直言),因为每次调用 arr 时都会初始化 getArr()

此外:你不能在另一个方法中使用 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;
}

关于c++ - 使用元编程计算log2但是 `compilation terminated`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52912736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com