部分专门化中不能推导模板形参
Template parameters not deducible in partial specialization
我有一个类似的问题,就像这里发现的一样,但它可能发生,我仍然在做一些不同的事情,所以我还是会问。
有一些类型将被标记为一个标签结构:
template<typename Geometry=void, typename Enable = void>
struct tag
{
typedef void type;
};
引入了、点标记和三角形标记:
struct point_tag {};
struct triangle_tag {};
使用std::vector
:
template<>
struct tag<std::vector<double>>
{
typedef point_tag type;
};
和一个三角形类型作为std::array
的别名模板:
template<typename Point>
using triangle =
typename std::enable_if
<
std::is_base_of<typename tag<Point>::type, point_tag>::value,
std::array<Point,3>
>::type;
如果作为Point
参数传递的参数确实标记为point_tag
,则启用,
之后,我想用triangle_tag
标记所有三角形,像这样:
template <typename Point>
struct tag<triangle<Point>>
{
typedef triangle_tag type;
};
std::array
是别名的,而不是组合/继承的,因为组合和继承会导致初始化列表构造的问题。但是,编译失败,报错
g++ -std=c++1y main.cpp -o main
main.cpp:31:8: error: template parameters not deducible in partial specialization:
struct tag<triangle<Point>>
^
main.cpp:31:8: note: ‘Point’
如果我不依赖于基于标记的Point
参数启用triangle
,但对所有类型都这样做:
template<typename Point>
using triangle =
// This works, but there is no restriction on Point to be tagged with point_tag.
std::array<Point, 3>;
则编译工作正常。然而,然后三角形也是一个三角形,我使用基于类型的任意属性的函数重载来减少那些enable_if
失败的函数的函数模板集。我不依赖函数模板的容器接口来确定可行的模板参数,因为有时隐式接口完全相同,但操作语义不同。例如,三角形是封闭的圆形线段(涉及3条边的操作),点链是开放的线段(涉及2条边的操作)。所有操作都需要一个直接访问操作符,这是模板参数的唯一要求,这导致在没有enable_if
限制的情况下实现函数模板实例化时产生歧义——所有这些都在链接的文章中讨论。
下面是完整的示例。
我错过了什么吗?如何解决这个问题?
为什么不使用Enable
模板参数?
比如:
template <typename Point>
struct tag<
std::array<Point, 3>,
typename std::enable_if<
std::is_base_of<
typename tag<Point>::type,
point_tag
>::value
>::type
>
{
typedef triangle_tag type;
};
(好的,你重复enable_if
…)
生活例子
这个适合我:
template <typename Point>
struct triangle
{
static_assert(std::is_same<typename tag<Point>::type, point_tag>::value, "triangle can only contain elements which model a point_tag.");
Point& operator[](std::size_t i) { return elems[i]; }
Point const& operator[](std::size_t i) const { return elems[i]; }
Point elems[3];
};
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 使用作为模板形参提供的基类成员,不带限定符
- 部分专门化中不能推导模板形参
- const迭代器的模板形参,而不是迭代器
- c++形参是一个指向常量对象的指针,但不返回更新后的对象
- 类模板特化,c++,模板形参列表中参数2不匹配
- 在c++中真的不可能跳过带有默认实参的模板形参吗?为什么语法不这么认为?
- 模板类中的模板迭代器,clang不能推断模板形参
- 为什么c++中通过引用传递的形参不需要解引用操作符
- 为什么标准不允许在模板形参列表中初始化依赖于常量的类型
- 通过函数实参而不是模板形参获取元组的元素
- 在函数实参中使用模板形参不适用gcc4.8
- 不能在模板专门化定义中将一个类的成员类型定义用作模板形参
- 传递给构造函数的形参不是类型
- 在c++的形参中传递多个参数而不使用va_list
- 在c++中,如何重载操作符而不通过形参传递对象
- 为什么在形参中使用initializer_list而不是vector ?
- 在不调用initializer_list构造函数的情况下,将不可复制、不可移动的类型构造为函数形参
- 为什么不允许使用不同数量的模板形参的类/结构声明?
- 模板类复制构造函数形参,带或不带模板实参