C++ c++;编译时检查函数参数
我正在寻找一种在编译时检查函数参数的方法,如果可能的话 更具体地说: 假设我们有一些类矩阵C++ c++;编译时检查函数参数,c++,C++,我正在寻找一种在编译时检查函数参数的方法,如果可能的话 更具体地说: 假设我们有一些类矩阵 class Matrix { int x_size; int y_size; public: Matrix(int width, int height): x_size{width}, y_size{height} {} Matrix(): Matrix(0, 0) {} }; int main() {
class Matrix
{
int x_size;
int y_size;
public:
Matrix(int width, int height):
x_size{width},
y_size{height}
{}
Matrix():
Matrix(0, 0)
{}
};
int main()
{
Matrix a; // good.
Matrix b(1, 10); // good.
Matrix c(0, 4); // bad, I want compilation error here.
}
所以,在传递给函数的静态(源代码编码)值的情况下,我是否可以检查或区分行为(函数重载?)
如果值不是静态的:
std::cin >> size;
Matrix d(size, size);
我们只能进行运行时检查。但如果值是在源代码中编码的呢?在这种情况下,我可以进行编译时检查吗
编辑:我认为这可以通过,但无论如何,使用和不使用constexpr重载都是不允许的。所以我认为这个问题无法以这种方式解决。要获得编译时错误,您需要一个模板:
template <int width, int height>
class MatrixTemplate : public Matrix
{
static_assert(0 < width, "Invalid Width");
static_assert(0 < height, "Invalid Height");
public:
MatrixTemplate()
: Matrix(width, height)
{}
};
模板
类MatrixTemplate:公共矩阵
{
静态_断言(0<宽度,“无效宽度”);
静态_断言(0<高度,“无效高度”);
公众:
MatrixTemplate()
:矩阵(宽度、高度)
{}
};
(顺便说一句:我建议索引使用无符号类型)
如果您没有静态断言(这里我切换到unsigned):
模板
类MatrixTemplate:公共矩阵
{
公众:
MatrixTemplate()
:矩阵(宽度、高度)
{}
};
模板类MatrixTemplate{};
模板类MatrixTemplate{};
模板类MatrixTemplate{};
此处不支持空矩阵(MatrixTemplate)。但是调整静态断言或类MatrixTemplate应该是一项简单的任务。线性代数软件包倾向于使用固定大小矩阵的模板,如:
模板类矩阵{…}
还有一个额外的矩阵类,可以在运行时更改大小
类动态矩阵{…}
当程序员需要固定大小的矩阵时,您仍然必须依赖于实际使用第一个选项的程序员,但是模板版本使得当x
或y
为零时,很容易生成编译器错误。运行时:
Matrix(int width, int height):
x_size{width},
y_size{height}
{
assert(x_size>0);
assert(y_size>0);
}
编译时(实际上,您不能使用函数参数。您可以使用模板方式):
模板
类矩阵
{
常量大小x大小=宽度;
常数大小y大小=高度;
静态_断言(宽度>0,“宽度必须>0”);
静态_断言(高度>0,“高度必须>0”);
};
您可以添加如下方法:
template <int WIDTH, int HEIGHT>
Matrix CreateMatrix()
{
static_assert(WIDTH > 0, "WIDTH > 0 failed");
static_assert(HEIGHT > 0, "HEIGHT > 0 failed");
return Matrix(WIDTH, HEIGHT);
}
int main() {
Matrix m(0, 2); // no static check
Matrix m2 = CreateMatrix<0,2>(); // static check
return 0;
}
模板
矩阵CreateMatrix()
{
静态_断言(宽度>0,“宽度>0失败”);
静态_断言(高度>0,“高度>0失败”);
返回矩阵(宽度、高度);
}
int main(){
矩阵m(0,2);//无静态检查
矩阵m2=CreateMatrix();//静态检查
返回0;
}
如果有人传递错误的参数,我认为不可能破坏编译。正常的方法是在错误的值上抛出异常,这就是小狗!我正准备编写代码。投票表决。您也可以使用constexpr
来实现这一点,但是某个编译器不支持它-(我这样想,但我假设矩阵大小在矩阵对象生命周期中不是恒定的。因此它是有效的,但在我的情况下不适用。您的代码中有一个输入错误:static_assert@AlexanderSergeev如果希望矩阵大小在运行时可能发生更改(为什么?),无论如何您都需要运行时检查。@Lumen我不想说我不需要运行时检查,但我想要两者。好主意。可以将工厂方法CreateMatrix
设置为Matrix
的静态成员函数,并将构造函数设置为私有。然后静态检查每个外部构造(如果需要的话)。
template <size_t WIDTH, size_t HEIGHT>
class Matrix
{
const size_t x_size = WIDTH;
const size_t y_size = HEIGHT;
static_assert(WIDTH > 0, "Width must > 0");
static_assert(HEIGHT > 0, "Height must > 0");
};
template <int WIDTH, int HEIGHT>
Matrix CreateMatrix()
{
static_assert(WIDTH > 0, "WIDTH > 0 failed");
static_assert(HEIGHT > 0, "HEIGHT > 0 failed");
return Matrix(WIDTH, HEIGHT);
}
int main() {
Matrix m(0, 2); // no static check
Matrix m2 = CreateMatrix<0,2>(); // static check
return 0;
}