質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

解決済

constexpr関数の利用方法について

asobinin
asobinin

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1回答

0評価

0クリップ

2015閲覧

投稿2019/01/09 12:19

コンパイル時定数を利用するにあたって、テンプレートメタプログラミングの他に、関数の前にconstexprを付けることでinline展開&コンパイル時計算が保証されるということをいくつかのサイトで拝見したことがあります。
そこで実験として、フィナボッチ数列を再帰関数を利用して計算し、その時間を計ってみることにしたのですが、その結果が
-constexpr関数 time[ms]:3713
-テンプレート time[ms]:0
-ノーマル関数 time[ms]:3617 (求める値を40にした場合)
となってしまいました。コンパイル時計算どころか、ノーマル関数より時間が掛かっています・・・

何故こうなったのか、記述が間違っているのか、あるいはそもそもの根本が間違っていたのかお教えください。

C++

#include <iostream> #include <chrono> using namespace std; // フィナボッチ数列(ノーマル) unsigned long fina(unsigned long n) { /*if (n <= 2) return 1; return fina(n - 1) + fina(n - 2);*/ return (n <= 2) ? 1 : (fina(n - 1) + fina(n - 2)); } // フィナボッチ数列(constexpr) constexpr unsigned long finaConst(unsigned long n) { return (n <= 2) ? 1 : (finaConst(n - 1) + finaConst(n - 2)); } // フィナボッチ数列メタプログラミング template <unsigned long N> struct Fina { enum { value = Fina<N-1>::value + Fina<N-2>::value }; }; template <> struct Fina<2> { enum { value = 1 }; }; template <> struct Fina<1> { enum { value = 1 }; }; // メイン関数 auto main() ->int { // 関数(constexpr)を利用した場合 auto start = chrono::system_clock::now(); cout << finaConst(40) << endl; auto end = chrono::system_clock::now(); cout << "constexpr time[ms]:" << (double)chrono::duration_cast<chrono::milliseconds>(end - start).count() << endl; // テンプレートを利用した場合 auto start2 = chrono::system_clock::now(); cout << Fina<40>::value << endl; auto end2 = chrono::system_clock::now(); cout << "template time[ms]:" << (double)chrono::duration_cast<chrono::milliseconds>(end2 - start2).count() << endl; // 関数(ノーマル)を利用した場合 auto start3 = chrono::system_clock::now(); cout << fina(40) << endl; auto end3 = chrono::system_clock::now(); cout << "nomal time[ms]:" << (double)chrono::duration_cast<chrono::milliseconds>(end3 - start3).count() << endl; return 0; }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。