C++ 模板化隐式类型转换运算符
我已经实施了C++ 模板化隐式类型转换运算符,c++,c++11,templates,casting,C++,C++11,Templates,Casting,我已经实施了 template<int M, int N, typename T=double> class matrix{ // ... } (甚至希望遇到矩阵的原因是某些矩阵表达式具有该类型。例如,将矩阵乘以矩阵计算结果为矩阵)您列出的代码不会编译,因为您实际上试图在T的定义之外实现T构造函数;或者,如果它是一个基本类型,或者是一个数组,那么它的意义就更小了 相反,您可以在matrix类中实现一个强制转换操作符,方法是将其添加到常规模板中,或者为M=1和N=1专门化ma
template<int M, int N, typename T=double>
class matrix{
// ...
}
(甚至希望遇到
矩阵
的原因是某些矩阵表达式具有该类型。例如,将矩阵
乘以矩阵
计算结果为矩阵
)您列出的代码不会编译,因为您实际上试图在T
的定义之外实现T
构造函数;或者,如果它是一个基本类型,或者是一个数组,那么它的意义就更小了
相反,您可以在matrix类中实现一个强制转换操作符,方法是将其添加到常规模板中,或者为M=1和N=1专门化matrix
第一个选项如下所示:
template<int M, int N, typename T=double>
class matrix{
// ...
operator T() const {
static_assert(M == 1 and N==1,
"Attempting to treat a matrix with multiple cells as a scalar");
// code to return the single matrix element
}
}
模板
类矩阵{
// ...
运算符T()常量{
静态断言(M==1和N==1,
“试图将包含多个单元格的矩阵视为标量”);
//返回单个矩阵元素的代码
}
}
第二点:
template<int M, int N, typename T=double>
class matrix{
// ...
}
template<typename T=double>
class matrix<1, 1, T>{
// ... some code duplication here with the main template; or maybe
// actually have different implementation banking on the fact that
// it's really just a scalar.
operator T() const {
// code to return the single matrix element
}
}
模板
类矩阵{
// ...
}
模板
类矩阵{
//…此处的一些代码与主模板重复;或者
//实际上有不同的实现基于这样一个事实
//它实际上只是一个标量。
运算符T()常量{
//返回单个矩阵元素的代码
}
}
但坦率地说,我不认为我会推荐这些选择中的任何一个。我可能会做以下一项:
- 改变取T的函数,使其可以“自然”取1x1矩阵(例如,通过模板)
- 改变取T的函数,使其可以“自然地”取任何矩阵。许多标量工作对矩阵有着有趣的推广
- 要明确转换,可以将
函数编写模板T作为标量(常量矩阵m)
- 将其放入类定义中:
template<int Md=M, int Nd=N, typename = std::enable_if_t<Md==1 && Nd==1>>
operator T() const {
return (*this)(0,0);
}
模板
运算符T()常量{
返回(*本)(0,0);
}
有无数函数,包括标准库中的许多函数,它们采用双精度
,而不是矩阵
。我认为这是隐式转换的一个很好的用法。每当我尝试专门化模板时,我都会有很多重复。static\u-assert
方法能否实现与模板专门化完全相同的功能,因为static\u-assert
在SFINAE中被视为替换失败?那么操作符std::enable\u if\u()const{…}
呢?@Museful:关于static\u-assert-我认为这不起作用,因为只有声明,而不是定义,被视为w.r.t.SFINAE;看见enable\u if\u t
听起来是个不错的选择。
template<int Md=M, int Nd=N, typename = std::enable_if_t<Md==1 && Nd==1>>
operator T() const {
return (*this)(0,0);
}