2016-04-29 6 views
2

私は唯一の0より大きい符号なし整数を受け入れ、それをチェックするために、デバッグアサートを持っている機能を持っている:コードはまだコンパイルしても、そのパラメータを受け入れるようパラメータがコンパイル時にわかっている場合は、オプションのstatic_assertを実行できますか?

void foo(unsigned int x) { 
    assert(x > 0); 
} 

は、ここstatic_assertを追加することが可能ですコンパイル時定数はありませんか?

foo(0); // compilation error 
foo(1); // fine 
foo(get_x_from_user()); // fine 

は、私は、テンプレートパラメータxを作ることができます知っているが、私はずっとコールのこのスタイルを維持することを好む:foo(5);ではなくfoo<5>();を。

カスタム整数型でこの問題を解決する方法があるかもしれないと思っていましたが、それほど遠くには到達できませんでした。これを行う方法はありますか?

+1

'static_assert'はコンパイル時に知られている値用ですが、' assert'は実行時に実行されます。 – CinCout

+0

'static_assert'を使って' x'をアサートするには 'x'は' constexpr'でなければなりません。 'get_x_from_user()'によって返されたランタイム値を 'constexpr'にすることができるかどうかはわかりません。 – wowofbob

+0

@CinCout、私は認識している..? –

答えて

1

私の知る限りでは、これは例えば、テンプレートのいくつかの種類を導入しなくては不可能である。

template<int T> 
class CustomInt 
{ 
public: 
    static constexpr int value = T; 
}; 

template<int val> 
void check(CustomInt<val> /*k*/) 
{ 
    static_assert(CustomInt<val>::value > 0, "error!"); 
    check(val); 
} 

void check(int k) 
{ 
    std::cout << "check"; 
} 

int s() 
{ 
    volatile int x = 5; 
    return x; 
} 

int main() { 
    check(CustomInt<0>()); 
    check(s()); 
    return 0; 
} 

これはちょうどかかわらず、カスタムタイプにテンプレートを移動します。

+1

私は最初にこのアイデアは好きではありませんでしたが、 'CustomInt'の代わりに' std :: integral_constant'を使用し、これを単にオーバーロードとして提供するのは、実際には素晴らしい解決策であると思います。彼らはstatic_assertが必要です)。ありがとう! –

1

foo(12)にこだわることはできません。コンパイラがコンパイル時に関数パラメータの値を知りたいからです。そして、それは不可能で、パラメータ値は実行時に評価されます。それでconstexprになることはできず、static_assertで使用することはできません。

関連する問題