【问题标题】:Defining a list class in c++ using variadic templates使用可变参数模板在 C++ 中定义列表类
【发布时间】:2017-06-22 10:12:03
【问题描述】:

我正在尝试使用 c++11 中的 vadiadic 模板定义一个 IntList 类,但我在语法上遇到了困难,我不确定如何初始化类字段。

我的最新版本如下:

template <int...>
struct IntList;

template<>
struct IntList<>{
    constexpr static bool empty = true;
    constexpr static int size = 0;
};

template<int Hd>
struct IntList<Hd>{
    constexpr static bool empty = false;
    constexpr static int size = 1;
    constexpr static int head = Hd;
    constexpr static IntList<> next = IntList<>();
};

template<int Hd, int... Rs>
struct IntList<Hd, Rs...>{
    constexpr static bool empty = false;
    constexpr static int size = sizeof ...(Rs);
    constexpr static int head = Hd;
    constexpr static IntList<Rs...> next = IntList<Rs...>();
};

我的列表类有 4 个字段,头部字段返回列表中的第一个数字,下一个字段返回列表的“尾部”。

对于包含 2 个或更多数字的列表和包含 1 个数字的列表和不包含 head 和 next 字段的空列表的 2 个基本案例,我有一个“一般”案例(空列表应该引发错误尝试访问其中之一时)。

当尝试测试我的列表时,行:

IntList<1, 2, 3>::next::next;

给我以下错误:

error: 'IntList<1, 2, 3>::next' is not a class, namespace, or enumeration
  IntList<1, 2, 3>::next::next;

尝试将 head 和 next 字段定义为常规(非静态)字段并在构造函数中对其进行初始化也会导致错误:

invalid use of non-static data member 'IntList<1, 2, 3>::head'
  IntList<1, 2, 3>::head;

这让我相信我实际上应该将这两个字段都定义为“静态”。

任何关于如何定义头部和下一个字段/我做错了什么的输入,将不胜感激!

【问题讨论】:

  • 你有一个潜在的模棱两可的过载情况。 IntList&lt;1&gt; 将与 struct IntList&lt;Hd&gt;struct IntList&lt;Hd, Rs...&gt; 匹配,并带有一个空的可变参数列表。您可以完全摆脱第二个模板声明。
  • 你为什么要做这一切???
  • 你知道有std::integer_sequence吧?
  • @SamVarshavchik 好点,我会删除它!
  • @Walter 作业:(

标签: c++ c++11 variadic-templates


【解决方案1】:

您可能想要声明一个类型而不是静态成员:

using next = IntList<Rs...>;

Demo

【讨论】:

  • 将行:constexpr static IntList&lt;Rs...&gt; next = IntList&lt;Rs...&gt;(); 更改为您所建议的会导致错误:error: declaration does not declare anything [-fpermissive] IntList&lt;1, 2, 3&gt;::next::next;
  • @Alice312:我刚刚添加了一个演示链接。
【解决方案2】:

这应该做你想做的事,大约一半的代码:

template<int...>
struct ints {
  constexpr static bool empty = true;
  constexpr static int size = 0;
};

template<int I0, int... Is>
struct ints<I0, Is...>{
  constexpr static bool empty = false;
  constexpr static int size = 1+sizeof...(Is);
  constexpr static int head = I0;
  using next = ints<Is...>;
};

现在:

using just_three = ints<1, 2, 3>::next::next;
static_assert( std::is_same<ints<3>, just_three>::value, "{3}=={3}" );

测试它。

Live example.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    相关资源
    最近更新 更多