静态成员定义中的双`template`关键字

时间:2017-01-17 11:28:36

标签: c++ c++11 templates static-methods

我暂时没有使用最新的C ++标准,今天我想在C ++中实现一个Haskell样式List,并提出如下内容:

template<typename T>
class List {
private:
    std::function<std::tuple<T,List<T>>()> f;
    List() {}
    List(T h, List<T> t) :f([h, t]() { return std::make_tuple(h, t); }) {}
public:
    typedef T item_type;

    static List<T> empty();

    static List<T> cons(T h, List<T> t);

    template<typename N, typename C>
    static auto on(N n, C c) -> decltype(N());
};

template<typename T>
List<T> List<T>::empty() {
    return List();
}
template<typename T>
List<T> List<T>::cons(T h, List<T> t) {
    return List([h, t](std::function<void(T, List<T>)> c) {f(c); });
}

template<typename T>
template<typename N, typename C>
auto List<T>::on(N n, C c) -> decltype(N()) {
    if (f == nullptr) return n();
    else {
        T h;
        List<T> t;
        std::tie(h, t) = f();
        return c(h, t);
    }
}

template<typename T, typename R, typename F>
R foldr(List<T> l, F f, R b) {
    return l.on([b]() { return b; }, [f, b](T h, List<T> t) { return foldr(t, f, f(t, b)); });
}

代码编译(VC 2015,尚未测试),但让我花一点时间找出函数on的正确语法。这是我第一次在C ++中看到类似这样的内容,双template关键字看起来很奇怪。

问题

当我们声明使用通过类模板不可用的模板变量的静态泛型方法时,这是正常的方法吗?任何人都可以在标准中指出一些条款吗?

1 个答案:

答案 0 :(得分:3)

  

当我们声明静态泛型方法时,这是否正常?   使用通过类模板不可用的模板变量?

是的,这是正常的。

  

有人能指出标准中的一些条款吗?

来自n4296, 14.5.2会员模板

  

可以在类或类模板中声明模板;这样的   模板称为成员模板。可以定义成员模板   在类定义或类模板定义之内或之外。一个   在其外部定义的类模板的成员模板   类模板定义应使用   类模板的模板参数后跟   成员模板的模板参数。 [例如:

template<class T> struct string {
    template<class T2> int compare(const T2&);
    template<class T2> string(const string<T2>& s) { / ... / }
};

template<class T> template<class T2> int string<T>::compare(const T2& s) {
}
     

-end example]