2013-09-24 86 views
7

我正在尋找一種方法來檢查函數參數在編譯時,如果它可以做編譯器。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() 
{ 
    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 constructor可能,但無論如何超載與無constexpr是不允許的。所以問題不能按我想的方式解決。

+0

我不認爲如果有人通過錯誤的參數是可以打破編譯。正常的方法是拋出錯誤值的異常 –

回答

4

要得到一個編譯時錯誤,您將需要一個模板:

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(這裏我切換到無符號):

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>應該是一件容易的事情。

+0

這就是小狗!我正要爲此編碼。有一個upvote。你也可以用'constexpr'來完成這個工作,但某個編譯器不支持它;-( – Bathsheba

+1

我這樣想,但是我認爲矩陣大小對於Matrix對象的生命週期並不是一成不變的。不適用於我的情況 –

+0

你的代碼有一個錯字:'static_assert <'而不是'static_assert('。 – Lumen

1

是線性代數軟件包的方式往往會做,這是使用模板爲固定大小的矩陣,如:

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

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

class DynamicMatrix {...}

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

0

運行時間:

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

您可以添加一個方法類似這個:

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; 
} 
+1

好主意。可以使工廠方法'CreateMatrix'成爲'Matrix'的靜態成員函數,並使構造函數爲私有。然後靜態檢查每個外部結構(如果需要的話)。 – Lumen