依赖于其他模板参数的模板参数
Template parameters that depend on other template parameters?
我发现了一些类似的问题(例如这个(,但没有一个真正回答我的问题。请考虑以下代码片段:
template<unsigned int rows, unsigned int cols,typename arrtype>
class Variance
{
double f(const arrtype &);
};
template<unsigned int rows, unsigned int cols>
double Variance<rows,cols,Eigen::Matrix<double,rows,cols>>
::f(const Eigen::Array<double,rows,cols> & M)
{
//do stuff
}
正如您在专业化中看到的那样,arrtype
的类型将取决于 rows
和 cols
.上面的代码导致编译器错误 (g++ 5.4.0(:
invalid use of incomplete type ‘class Variance<rows, cols, Eigen::Matrix<double, rows, cols> >
我已经尝试在模板声明中typename arrtype<rows, cols>
,但随后它抱怨arrtype
不是一种类型,这是有道理的。
使用依赖于其他模板化类型的模板化类型的正确方法是什么?
这是代码的简化版本:
template<size_t rows, size_t cols> struct Foo { double foo(); };
template<size_t rows> double Foo<rows,3>::f() { return 3;}
您收到的错误:
error: invalid use of incomplete type ‘struct Foo<rows, 3ul>’
double Foo<rows,3>::f() { return 3;}
问题不在于您的某个模板参数依赖于其他参数,而是您无法在不部分专用化类的情况下部分专用化成员。
这有效:
template<size_t rows, size_t cols> struct Foo { double foo(); };
template<size_t rows> struct Foo<rows,3> { double f() { return 3;} };
部分类专用化的替代方法(如 user463035818 的答案((或尝试完全专用化函数(是一种称为标记调度的技术。
执行此操作的方法是创建要调度到的重载帮助程序函数,并允许基于参数参数接管正常重载。
下面我将展示如何专注于Eigen::Array<double, rows, cols>
:
template<unsigned int rows, unsigned int cols,typename arrtype>
class Variance
{
public:
double f(const arrtype& arg)
{
return f_impl(arg, tag<arrtype>{});
}
private:
template<class... T>
struct tag{};
template<class... T>
double f_impl(const arrtype&, tag<T...>){
std::cout << "catch-all functionn";
return 42.0;
}
double f_impl(const arrtype&, tag<Eigen::Array<double, rows, cols>>){
std::cout << "specialization for Eigen::Array<double, rows, cols>n";
return 1337.0;
}
};
现在你可以这样称呼它:
Variance<1, 1, int> non_specialized;
non_specialized.f(int{}); // prints "catch-all function"
Variance<1, 1, Eigen::Array<double, 1, 1>> specialized;
specialized.f(Eigen::Array<double, 1, 1>{}); // prints "specialization for Eigen::Array<double, rows, cols>"
演示
当您想要避免复制粘贴基本模板类和专用类的几乎相同的函数,或者将所有内容放入某个公共基库并使用多态性时,标记调度非常有用。
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 如何从其他功能C++访问参数?
- C++ 默认参数使用其他参数
- 如何将将参数包作为参数传递给其他模板类的模板类?
- lambda 作为接受其他参数的参数的初始化顺序
- 如何在其他类中使用参数化构造函数制作类的对象?
- 模板参数包如何具有其他尾随参数?
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- 了解'this'或其他参数是否为右值
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 推断大多数模板对象的参数,但在调用模板函数时对其他对象显式
- 当模板类使用参数包时,如何传递其他模板参数
- 如何将char数组声明为函数参数?或告诉我此代码中还有其他问题?
- 递归回文检查,不使用向量、大小或其他参数
- 将成员函数作为参数传递给其他成员函数 (C++ 11 <function>)
- 依赖于其他模板参数的模板参数
- 传递多个参数的功能,该函数将类包含到其他函数
- 将指针类方法作为参数传递给其他类方法C
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- 如何根据枚举参数返回其他类型