过程中使用非类型模板参数考虑以下struct
S:偏特
//Implementations provided elsewhere
struct A { A(int i, double d, std::string s); /* ... */ };
struct B { B(double d1, double d2); /* ... */ };
我有两个转换类,它们的模板签名的样子:
TupleAs< A, int, double, std::string > via1 { ... };
ArrayAs< B, double, 2 > via2 { ... };
可以预见的是,TupleAs
转换的三重int
,double
和std::string
值转换成A
类型的对象。同样,ArrayAs
将一对两个double
值转换为B
类型的对象。 (是的,是有原因的,我不能直接调用A
和B
构造函数)。
提高语法
我想改变语法,所以我可以做到以下几点:
TupleAs< A(int,double,std::string) > via1 { ... };
ArrayAs< B(double,2) > via2 { ... };
我认为这更多地描述了转换过程。该TupleAs
模板声明和相应的局部专业化应该是这样的:
template <typename T> struct TupleAs;
template <typename T, typename ... Args>
struct TupleAs<T(Args...)> { ... };
编译器错误
但是,如果我尝试做与ArrayAs
版本类似的东西:
template <typename T> struct ArrayAs;
template <typename T, typename U, unsigned N>
struct ArrayAs<T(U,N)> { ... };
我尝试实例化时在叮当(3.6)中出现以下错误(ArrayAs< B(double,2)> test;
):
typeAs.cpp:14:22: error: unknown type name 'N'
struct ArrayAs<T(U,N)>{
^
typeAs.cpp:14:10: warning: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used
struct ArrayAs<T(U,N)>{
^~~~~~~~~~~~~~~
typeAs.cpp:13:45: note: non-deducible template parameter 'N'
template<typename T, typename U, unsigned N>
^
gcc错误诊断有点不同,但我不会在这里发表。我承认我的模板技能应该比他们更好,我也承认类似的std::function<B(double,2)>
声明显然是无稽之谈。但有人可以告诉我为什么我不想让特定的语法实现吗?我查看了C++ 14标准,并且无法找到相关部分,而且我在解释叮当声诊断消息时遇到了问题。
您正在专注于功能类型。函数类型的形式为'type(types ...)',没有空间存放整数。换句话说,在任何情况下,B(double,2)语法在C++中都没有意义。错误消息可以承认更有意义。 – Quentin
你需要'2'作为编译时参数吗? – sfjac