C++ 在部分专门化期间使用非类型模板参数

C++ 在部分专门化期间使用非类型模板参数,c++,c++11,C++,C++11,考虑以下结构: //其他地方提供的实现 结构A{ainti,double d,std::string s;/*…*/}; 结构B{Bdouble d1,double d2;/*…*/}; 我有两个转换类,其模板签名如下所示: 元组via1{…}; ArrayAsvia2{…}; 可以预见,TupleAs将int、double和std::string值的三元组转换为a类型的对象。类似地,ArrayAs将两个double值的对转换为B类型的对象。是的,我无法直接调用a和B构造函数是有原因的 改进语法

考虑以下结构:

//其他地方提供的实现 结构A{ainti,double d,std::string s;/*…*/}; 结构B{Bdouble d1,double d2;/*…*/}; 我有两个转换类,其模板签名如下所示:

元组via1{…}; ArrayAsvia2{…}; 可以预见,TupleAs将int、double和std::string值的三元组转换为a类型的对象。类似地,ArrayAs将两个double值的对转换为B类型的对象。是的,我无法直接调用a和B构造函数是有原因的

改进语法

我想更改语法,以便执行以下操作:

元组via1{…}; ArrayAs通过2{…}; 我认为,这更能描述转换过程。TupleAs模板声明和相应的部分专门化如下所示:

模板结构元组; 样板 结构元组{…}; 编译器错误

但是,如果我尝试对ArrayAs版本执行类似操作:

模板结构ArrayAs; 样板 结构ArrayAs{…}; 在尝试将Clang3.6实例化为ArrayAstest;,我在其中遇到了以下错误:

gcc错误诊断有点不同,但我不会在这里发布

我承认我的模板技术应该比现在更好,我也承认类似的std::function声明显然是胡说八道。但是有人能告诉我为什么我试图实现的特定语法是不允许的吗?我浏览了C++14标准,发现相关部分很难找到,而且我在解释叮当声诊断消息方面也有困难。

当您专门化TupleAs时:

不存在接受N的函数。它可以接受无符号,但不能接受值。根本就没有这样合理的事情。从您的示例B来看,2根本没有意义。充其量,您可以编写一些允许:

template <unsigned N> using size_ = std::integral_constant<size_t, N>;

ArrayAs< B(double,size_<2>) >
甚至:

ArrayAs< B(std::array<double, 2>) >
从现在起,我们又回到了到处使用类型。不管你喜欢与否,这是个人的偏好

这里的关键是,当涉及到模板元编程的所有事情时,类型都是一流的公民,应该尽可能避免使用值

template <typename T> struct ArrayAs;

template <typename T, typename U, std::size_t N>
struct ArrayAs<T(std::array<U,N>)> { ... };
工程,以及:

template<class T>
struct to_array;
template<class T, size_t N>
struct to_array< T[N] > { using type = std::array<T, N>; };
template<class T>
using arr = typename to_array<T>::type;
然后:


遗憾的是,由于函数类型中的数组如何衰减为指针,直接使用ArrayAs不起作用。

您专门研究函数类型。函数类型的形式是typetypes…,不能容纳整数。反过来说,B2OP,2语法在C++中没有意义,在任何上下文中都没有意义。不可否认,错误消息可能更有意义。你需要2作为编译时参数吗?@yakkarayas需要,但很恶心。责怪数组衰退:pYes,从根本上说,我试图专门研究函数类型。这正是我需要听到的。谢谢。@Barry不工作,因为它需要一个decltype。勾画、构建和吸收——文字是值,而不是类型d'oh。我没有想过尝试数组订阅语法。谢谢你。但是,唉,因为腐烂。。。
ArrayAs< B(std::array<double, 2>) >
template <typename T> struct ArrayAs;

template <typename T, typename U, std::size_t N>
struct ArrayAs<T(std::array<U,N>)> { ... };
template<class T>
struct to_array;
template<class T, size_t N>
struct to_array< T[N] > { using type = std::array<T, N>; };
template<class T>
using arr = typename to_array<T>::type;
ArrayAs< Bob( arr<int[3]> ) > some_var;