微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

递归可变参数模板的基本案例专业化

如何解决递归可变参数模板的基本案例专业化

我的目标是定义一个Recursive类,该类以int N为模板,以及一个或多个类型T,...Ts,其行为应类似于std::pair

  • 其中std::array个类型为N的{​​{1}}个项目中的一个T
  • ,以及作为first 可选 second,其中std::vector实例化在同一Recursive上,其余模板参数N

在尝试根据上述要求写下该类时,我想出了这个无效的代码在这里,我还定义了一些必要的,因为它们有很大帮助,它们是{{1 }}),而且我不知道是否对我上面描述的内容进行了错误的设计(或者它是格式不正确的描述!),或者是否滥用了语言语法。

Ts...

我将添加到目前为止已完成的一些故障排除。在下文中,模板指定似乎可以正常工作。

Recursive

解决方法

您的错误是,首先,您声明Recursive接收至少一个整数和两个类型,然后,您声明了部分特殊化,接收一个整数以及一种类型。

错误,因为在声明主模板接收两种或多种类型时,专业化不能仅接收一种类型。

可能违反直觉,但可以声明解决方案Recursive仅接收一个一种类型(或更多)(这成为递归的基础),而特殊化则接收两种类型或更多

template <int N,typename T1,typename...>
struct Recursive : std::array<T1,N>
 { };

template <int N,typename T2,typename ...Ts>
struct Recursive<N,T1,T2,Ts...>
   : std::pair<std::array<T1,N>,boost::hana::optional<std::vector<Recursive<N,Ts...>>>>
 { };

以下内容几乎没有修改(对于大小,用std::size_t代替了int;用std::optional代替了boost::hana::optional),但是完全编译了示例

#include <array>
#include <optional>
#include <string>
#include <utility>
#include <vector>

template <std::size_t N,N>
 { };

template <std::size_t N,std::optional<std::vector<Recursive<N,Ts...>>>>
 { };

template<typename ...T>
using Recursive2 = Recursive<2u,T...>;

template<typename ...T>
using Recursive3 = Recursive<3u,T...>;

int main ()
 {
    Recursive2<int> x{std::array<int,2u>{0,0}};
    Recursive3<int,long> y{{std::array<int,3u>{0,0},{}}};
 }
,

您有几个问题:

  • 您的专业与您的主要模板不匹配

    template <int N,typename ...Ts> struct Recursive;至少需要3个参数。我认为应该是专业化的,主要模板应该是:

    template <int N,typename ...Ts>
    struct Recursive;
    
  • template <int N,typename T> struct Recursive<N,T>的行为不像std::pair(在您声明要求时,否则用法是错误的),您可能想要以下内容:

    template <int N,typename T>
    struct Recursive<N,T> : std::pair<std::array<T,decltype(boost::hana::nothing)>
    
  • 您需要“转发”基类的构造函数,(也可以选择使用合成代替继承,或者使用特质来定义要使用的类型)或更改构造对象的方式。

结果是:

template <int N,typename ...Ts>
struct Recursive;

template <int N,Ts...>
    : std::pair<std::array<T1,Ts...>>>
                            >
{
    using std::pair<
        std::array<T1,Ts...>>>>::pair;
};

template <int N,T>
    : std::pair<std::array<T,decltype(boost::hana::nothing)>
{
    using std::pair<std::array<T,decltype(boost::hana::nothing)>::pair;
};

template<typename ...T>
using Recursive2 = Recursive<2u,T...>;

int main() {
    using boost::hana::nothing;
    Recursive2<int> x(std::make_pair(std::array<int,2>{0,nothing));
}

Demo

,

我添加了自己的答案,因为我确实找到了解决方案(虽然在收到两个答案之前有点;但是使用std::optional是我后来对其中一个答案做出的较晚更改)。但是,在我的解决方案中,我必须声明和定义通用模板和专用模板的构造函数,这使我认为它不如其他答案那么好。但是为什么不发布呢?

#include <cassert>
#include <iostream>
#include <array>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

template <int N,typename T,typename ...Ts>
struct Recursive : std::pair<std::array<T,Ts...>>>
                   > {
    template<typename ...Args>
    Recursive(Args&& ...args) : std::pair<std::array<T,Ts...>>>
                  >(args...) {}
};

template <int N,T> : std::array<T,N> {
    template<typename ...Args>
    Recursive(Args&& ...x) : std::array<T,N>(x...) {}
};


template<typename ...T>
using Recursive2 = Recursive<2u,T...>;

int main() {
    std::array<std::string,2> twoStrings{"hello","Hello"};
    std::array<char,2> twoChars{'h','H'};

    Recursive2<std::string> s{twoStrings};
    assert(s == twoStrings);

    std::vector<Recursive2<char>> vecOfTwoChars{twoChars,twoChars,twoChars};

    Recursive2<std::string,char> sc{twoStrings,vecOfTwoChars};
    assert(sc.first == twoStrings);
    assert(sc.second->size() == 3);
    assert(sc.second == vecOfTwoChars);
    assert(sc.second.value()[0] == twoChars);

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?