簡體   English   中英

c ++編譯時檢查函數參數

[英]c++ compile-time check function arguments

如果可以為編譯器做的話,我正在尋找一種在編譯時檢查函數參數的方法。

更具體一點:假設我們有一些類Matrix。

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構造函數實現 ,但無論如何都不允許使用和不使用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)
    {}
};

(順便說一句:我建議索引的無符號類型)

如果你沒有static_assert(這里我切換到unsigned):

template <unsigned width, unsigned height>
class MatrixTemplate : public Matrix
{
    public:
    MatrixTemplate()
    : Matrix(width, height)
    {}
};

template <> class MatrixTemplate<0, 0> {};
template <unsigned height> class MatrixTemplate<0, height> {};   
template <unsigned width> class MatrixTemplate<width, 0> {};

這里不支持空矩陣(MatrixTemplate <0,0>)。 但是調整static_asserts或類MatrixTemplate <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;
}

線性代數包傾向於這樣做的方式是使用固定大小矩陣的模板,如:

template<int x, int y> class Matrix { ... }

和一個可以在運行時改變大小的矩陣的額外類

class DynamicMatrix {...}

當他們想要固定大小的矩陣時,您仍然必須依賴程序員實際使用第一個選項,但是當xy為零時,模板版本可以很容易地生成編譯器錯誤。

運行:

Matrix(int width, int height):
    x_size{width},
    y_size{height}
{
        assert(x_size>0);
        assert(y_size>0);
}

編譯時(實際上你無法使用函數參數。你可以使用模板方式):

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");
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM