是否可以声明模板的模板?

问题描述

我有C ++中来自OCaml的类型为“值”的对象(它们由某个集成渠道提供,但这是题外话)。该对象包含某种类型的OCaml数据(原始:int,long ...或结构化)。可以通过“ caml / mlvalues.h”函数(例如Int_val(Long_val,Bool_val ...))提供的某些功能将其转换为C ++对象,从OCaml int转换为C ++ int等。

我通过T to<T>(value x)名称空间中的某些模板函数Caml::Value包装了来自“ caml / mlvalues.h”的函数,以提高可读性。 (Caml :: Value :: to 比Bool_val更好)。

caml.h:

namespace Caml::Value {
  template<typename T> struct CannotConvertTo { };
  template<typename T> T to(value x);

caml.cpp:

namespace Caml::Value {
  template<typename T> T to(value x) {
    if (is_enum<T>::value) {
      return static_cast<T>(to<int>(x));
    }

    throw CannotConvertTo<T>();
  }
  
  template<> int to<int>(value x) {
    return Int_val(x);
  }

  template<> bool to<bool>(value x) {
    return Bool_val(x);
  }
}

“值”也可以包含某些结构,我们可以通过功能Field(value,index)读取此结构的字段。而且我尝试实现一些通用的实现,以将“值”转换为元组

  template<> tuple<T1,T2> to<tuple<T1,T2>>(value x) {
    return make_tuple<T1,T2>(
      to<T1>(Field(x,0)),to<T2>(Field(x,1))
    );
  }

当然,由于类型T1和T2未知,因此它是不可编译的代码。如何实现to<tuple<T1,T2>>()?是否可以声明类似模板的模板?喜欢:

template<typename T1,typename T2> 
template<> tuple<T1,T2>>(value x) {
...
}

解决方法

您可以将操作从功能模板转发到类模板,并对其进行专门化,而使前者完全通用。

// base case: conversion disallowed
template <typename K>
struct convert_to
  { static K convert_to(value) = delete; };

// convert to specific types                                
template <> struct convert_to<int> 
  { static int convert(value); };
template <> struct convert_to<bool> 
  { static bool convert(value); };
template <typename L,typename R> struct convert_to<std::pair<L,R>> 
  { static std::pair<L,R> convert(value); };

// function template,never specialised
template <typename K> K to(value x) 
  { return convert_to<K>::convert(x); }