C++ 仅在部分专门化中提供方法
我有classC++ 仅在部分专门化中提供方法,c++,templates,c++17,template-specialization,C++,Templates,C++17,Template Specialization,我有classMatrix,如果R=3和C=1,我想要一个len()的专门方法。 我想有一个标准库的解决方案。 继承不是解决方案,因为它在基类上也不起作用 正规模板专门化 模板 类矩阵{ 公众: T len()常量{return 3;} }; 会迫使我实现所有其他的Matrix方法等等。(?) 想法: std::启用_if constexpr #包括 样板 类矩阵{ 私人: std::矢量数据; 公众: T len()常数; }; 肮脏的解决方案是: 模板 T矩阵::len()常量{
Matrix
,如果R=3
和C=1
,我想要一个len()的专门方法。
我想有一个标准库的解决方案。
继承不是解决方案,因为它在基类上也不起作用
正规模板专门化
模板
类矩阵{
公众:
T len()常量{return 3;}
};
会迫使我实现所有其他的Matrix
方法等等。(?)
想法:
- std::启用_if
- constexpr
#包括
样板
类矩阵{
私人:
std::矢量数据;
公众:
T len()常数;
};
肮脏的解决方案是:
模板
T矩阵::len()常量{
如果constexpr(R==3&&C==1){
返回3;
}
抛出std::运行时_错误(“len不可用”);
}
一种可能的方法:
解释作为注释:
#include <iostream>
template<class T, int R, int C>
struct Matrix;
namespace MatrixOperations
{
// default handling is to prevent compilation
template<class Mat>
auto len(Mat const&) -> void = delete;
// special case for a 3,1 matrix
template<class T>
auto len(Matrix<T, 3, 1> const&) -> T
{
return T(3);
}
};
template<class T, int R, int C>
struct Matrix
{
// ForceDeduce is a defaulted type.
// The argument of this type is defaulted
// It's purpose is to ensure that this function is not actually compiled until it is used
// This will prevent the call to MatrixOperations::len producing an error unless this function
// is called
template<class ForceDeduce = int*>
T len(ForceDeduce = nullptr) const
{
return MatrixOperations::len(*this);
}
};
int main()
{
Matrix <int, 3, 1> m31;
std::cout << m31.len() << std::endl;
Matrix <int, 3, 2> m32;
// fails to compile
// std::cout << m32.len() << std::endl;
}
#包括
样板
结构矩阵;
命名空间矩阵操作
{
//默认处理是防止编译
样板
自动len(Mat const&->void=delete;
//3,1矩阵的特例
样板
自动长度(矩阵常数&)->T
{
返回T(3);
}
};
样板
结构矩阵
{
//ForceDestruction是默认类型。
//此类型的参数为默认值
//它的目的是确保在使用该函数之前不会实际编译它
//这将防止对MatrixOperations::len的调用产生错误,除非此函数
//被称为
样板
T len(force演绎=nullptr)常数
{
返回矩阵运算::len(*this);
}
};
int main()
{
矩阵m31;
std::cout一种可能的方法:
解释作为注释:
#include <iostream>
template<class T, int R, int C>
struct Matrix;
namespace MatrixOperations
{
// default handling is to prevent compilation
template<class Mat>
auto len(Mat const&) -> void = delete;
// special case for a 3,1 matrix
template<class T>
auto len(Matrix<T, 3, 1> const&) -> T
{
return T(3);
}
};
template<class T, int R, int C>
struct Matrix
{
// ForceDeduce is a defaulted type.
// The argument of this type is defaulted
// It's purpose is to ensure that this function is not actually compiled until it is used
// This will prevent the call to MatrixOperations::len producing an error unless this function
// is called
template<class ForceDeduce = int*>
T len(ForceDeduce = nullptr) const
{
return MatrixOperations::len(*this);
}
};
int main()
{
Matrix <int, 3, 1> m31;
std::cout << m31.len() << std::endl;
Matrix <int, 3, 2> m32;
// fails to compile
// std::cout << m32.len() << std::endl;
}
#包括
样板
结构矩阵;
命名空间矩阵操作
{
//默认处理是防止编译
样板
自动len(Mat const&->void=delete;
//3,1矩阵的特例
样板
自动长度(矩阵常数&)->T
{
返回T(3);
}
};
样板
结构矩阵
{
//ForceDestruction是默认类型。
//此类型的参数为默认值
//它的目的是确保在使用该函数之前不会实际编译它
//这将防止对MatrixOperations::len的调用产生错误,除非此函数
//被称为
样板
T len(force演绎=nullptr)常数
{
返回矩阵运算::len(*this);
}
};
int main()
{
矩阵m31;
std::cout一个简单的解决方案
#包括//std::启用#
#include//std::vector
样板
类矩阵{
私人:
std::矢量数据;
公众:
样板
std::size\u t len()常量{
双res=0;
用于(常量自动和x:数据){
res+=std::pow(x,2);
}
返回标准::sqrt(res);
}
};
替代性越界定义:
模板
类矩阵{
私人:
std::矢量数据;
公众:
样板
双len()常数;
};
样板
样板
双矩阵::len()常量{
双res=0;
用于(常量自动和x:数据){
res+=std::pow(x,2);
}
返回标准::sqrt(res);
}
例如:
#包括//std::cout,std::endl
int main(int argc,char*argv[]){
矩阵向量机;
std::cout一个简单的解决方案
#包括//std::启用#
#include//std::vector
样板
类矩阵{
私人:
std::矢量数据;
公众:
样板
std::size\u t len()常量{
双res=0;
用于(常量自动和x:数据){
res+=std::pow(x,2);
}
返回标准::sqrt(res);
}
};
替代性越界定义:
模板
类矩阵{
私人:
std::矢量数据;
公众:
样板
双len()常数;
};
样板
样板
双矩阵::len()常量{
双res=0;
用于(常量自动和x:数据){
res+=std::pow(x,2);
}
返回标准::sqrt(res);
}
例如:
#包括//std::cout,std::endl
int main(int argc,char*argv[]){
矩阵向量机;
std::cout@Evg:他希望将一行矩阵视为向量,因此具有向量功能,如计算长度。“正常的模板专门化[…]将迫使我实现所有其他矩阵方法和东西。”如果您拆分基本矩阵
实现和可自定义部分,则应避免重复。C++20将具有要求
静态断言(R==3&&C==1)
似乎比抛出要好。@Evg:浮点向量应该在浮点中有一个长度。此外,为什么需要将其限制为3列向量也不是特别相关;问题是如何做到这一点。@Evg:他希望将一行矩阵视为向量,因此具有计算长度的向量功能。“正常的模板专门化[…]会迫使我实现所有其他矩阵
方法和东西。”如果你将基本矩阵
实现和可定制部分分开,你应该避免重复。C++20将有要求
静态断言(R==3和&C==1);
似乎比throw好。@Evg:float向量应该在float中有一个长度。另外,为什么需要将其限制为3列向量也不是特别相关;问题是如何做。一旦你费尽心思制作了矩阵::len
模板,为什么不让它成为一个友好的模板呢(没有名称空间版本也可以吗)?一旦你费尽心机制作了Matrix::len
一个模板,为什么不让它变得友好(没有名称空间版本也可以)?如何声明它呢?template template T Matrix::len()const{return std::sqrt(std::pow(this->v(0),2)+std::pow(this->v(1),2)+std::pow(this->v(2),2));}
似乎不可能。如何声明它不符合要求?模板T矩阵::len()常量{