2016-09-11 5 views
4

コンパイラにconstexprまたは関数への非可変入力のみを受け入れるように強制できますか?コンパイラがコンパイル時の引数(浮動小数点)のみを受け入れるようにする

私は関数にコンパイル時の値だけを許可したいのですが。テンプレートまたはその他の方法を使用しています。

Hereには、intテンプレートの実例があります。 doubleの問題は、それらをテンプレート引数として使用できないことです。重複したとして、この質問をマークしている人たちへの更新

#include <iostream> 

template <double x> 
void show_x() 
{ 
    std::cout<<"x is always "<<x<<" in the entire program."<<std::endl; 
} 

int main() 
{ 
    show_x<10.0>(); 
    return 0; 
} 

error: ‘double’ is not a valid type for a template non-type parameter


、私が言っている:

私が尋ねる質問

How to solve problem A?

Solution B does not work for problem A, I need another solution

は、その後、あなたはソリューションBが動作しない理由を私にリンクさ。

これは全く論理的ではありません。

更新:ユーザー迂回に関する

懸念が対処されました。ここ

+2

@ m.s。、なぜ私は 'double'からテンプレートを作ることができないのですか?私はどのように関数にコンパイル時の値だけを許すことができるのか尋ねています。テンプレートまたはその他の方法を使用しています。 – ar2015

+0

明確にするために、なぜこれを通常の関数パラメータとして渡せませんか? –

+0

@OliverCharlesworth、セキュリティ上の理由から。私は時間同期のためにこの関数を使用する予定であり、そうでなければステップ時間が変わるべきではありません。そうでなければ、予測できない振る舞いが起こります。この問題を回避する方法は常にあります。しかし、私はこのように解決することを好む。 – ar2015

答えて

3

私は正確に何をしたいか分からないが、ここでは関数呼び出しで非定数式を拒否するための方法です。残念ながら、それがために名前の汚染の悪いマクロを使用しますが、多分あなたはあなたの関数を与える場合は奇妙な名前が、それはあまりにも傷つけることはありません。

void f(double d) {} 
#define f(x) do { constexpr decltype(x) var = x; f(var); } while (0) 

int main() 
{ 
    f(1.0);  // OK 
    f(1 + 2); // OK, constant expression with implicit conversion 
    double e = 5.0; 
    f(e);  // compilation error, `e` is not a constant expression 
} 

そうでない定数式を拒否したい場合正確にはdoubleタイプです。これも可能です(あなたの質問にはそれが必須かどうかは不明です)。

4

は2通りあります。今、X::value()は、使用される前に関数本体内の変数constexprによって取得されます。 Xvalue()というconstexprメソッドなしで渡すことはできません。

#include <iostream> 


    struct always_10 
    { 
    constexpr static double value() { return 10.0; } 
    }; 

template <class X> 
void show_x() 
{ 
    constexpr auto x = X::value(); 
    std::cout<<"x is always "<< x <<" in the entire program."<<std::endl; 
} 

template<class X> 
void show_x(X x_) 
{ 
    constexpr auto x = x_.value(); 
    std::cout<<"x is always "<< x <<" in the entire program."<<std::endl; 
} 

int main() 
{ 
    show_x<always_10>(); 
    show_x(always_10()); 
    return 0; 
} 
+1

あなたの方法は正常に動作します。しかし、 'constexpr'は' show_x'のための必須条件ではありません。 1人のユーザーが誤ってライブラリを回ることがあります。 – ar2015

+0

@ ar2015私は分かりません。 –

+0

ar2015は、制約を強制する関数そのものではなく、制約を適用する特定の型のオブジェクトを渡すことを忘れないようにしなければならないので、これはちょっとしたことだと思います。このように、多くの場合、まともな実用的な解決策になるかもしれません(そして、私は個人的にはそれ以上に気にしません)が、なぜar2015がこれが本当に質問の精神を満たしていないと信じているのか分かります。 –

関連する問題