2

どの type_traits またはメソッドでも、パラメーターが constexpr であるかどうかを確認できますか?

size_t fibo_runtime(size_t num)
{
  //implementation
}

constexpr size_t fibo(size_t num)
{
    return is_constexpr<size_t>::value ? //this type traits looks weird and unreasonable
           (num > 1 ? fibo(num - 1) * num : 1) :
           fibo_runtime(num);
}

constexpr は constexpr パラメータに適用でき、パラメータは実行時に決定されます。ただし、再帰は実行時に十分に効率的でない場合があります。

constexpr 関数の実行時とコンパイル時の実装を分離する必要がありますか? それができない場合、ユーザーが constexpr 関数を使用してランタイム評価を実行できないようにすることはできますか?

4

3 に答える 3

0

関数内では、パラメーターをチェックして、完全な呼び出し式が定数式であるかどうかを確認することはできません。ただし、呼び出しサイトにマクロを実装して同じことをテストし、式が定数式であるかどうかに応じて、true_typeまたはfalse_typeコンパイル時に評価することができます

IS_A_CONSTANT_EXPRESSION(  fibo(5)          )    // is constant
IS_A_CONSTANT_EXPRESSION(  fibo(time(NULL)  )    // is not constant

詳細は別の質問へのこの回答にあります。(私自身の答え、クロス投稿をお詫びします!)

次に、別のマクロを実装FIBO( expr )して、これを適切にまとめ、適切なバージョンを呼び出すことができます。

于 2016-11-04T07:42:32.613 に答える
0

定数式 ( constexpr)の本質は定数であることです。そのため、実行時の評価であろうとなかろうと、それらの動作は変更されず、実行時に評価が行われることはありません。

実行時に関数を使用する場合constexpr(単純に呼び出すだけではありません)、通常の関数として呼び出されます。これは、式が実行時に定数として本質的に解決できないためです。

コンパイル時またはランタイムに応じていくつかの異なる実装を実現したい場合、関数の呼び出し方法によっては同じ動作が得られないため、(それを実現した場合) 開発者にとっては非常に厄介です! したがって、そのような動作は実装できない/実装しない/実装すべきではないことが明らかになります。

関数をコンパイル時の計算に特化したい場合は、別の関数を使用して意図を明確に記述します。

于 2013-03-05T23:23:59.387 に答える
-3

私はこれがあなたが望むものを手に入れるかもしれないと思います

#include <iostream>

template <typename T>
class is_constexpr
{
   typedef char true_type ;
   struct false_type { true_type _[2] ; } ;

   template <typename U>
   static true_type has_constexpr( U & ) ;

   template <typename U>
   static false_type has_constexpr(...) ;

   public:
      enum { value = ( sizeof(has_constexpr<T>(0)) == sizeof(true_type)) } ;
} ;

int main()
{
   constexpr int i = 10 ;
   int k = 20 ;

   std::cout << is_constexpr<decltype(i)>::value << std::endl ;
   std::cout << is_constexpr<decltype(k)>::value << std::endl ;   
}

参考としてSFINAEの理解を使用しました。

さらに調査を行うと、質問の他の部分の答えは「はい」だと思います。これは、constexpr関数テンプレートが定数式で常に使用できるとは限らないためです。したがって、これはそのような解決策につながります。このやや不自然な例を使用します。

template <typename T>
T f2( T num )
{ 
   return num + 1;
}

template <typename T>
constexpr T f1( T num )
{
   return num ;
}

template <typename T>
constexpr T f(T num)
{
   return  is_constexpr<T>::value ? f1(num) : f2(num) ;
} 
于 2013-03-06T03:44:20.233 に答える