BenBecky
@BenBecky (Ben Becky)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

[ C++ ] 名前空間内での条件分岐について

[ C++ ] 名前空間内での条件分岐について

閲覧ありがとうございます.
C++98 にて以下のプログラムを実装中です.

現在,「test0.inc」,および「test1.inc」ファイルで名前空間を定義し,それぞれを「main.cpp」ファイルに読み込み使用するプログラムを作成しています.
そこで,「test1.inc」で定義した名前空間内の定数(constexpr int型)の値を,条件に応じて変更したいです.
今はラムダ式を用いて条件分岐を行おうと考えており,以下のように記述していますが,コンパイル時にエラーがでてしまっています. 
これを解決して条件に応じて値を変更できるようにしたいです. 

以下記述したコード

constexpr int 型の変数iに対して以下のような記述をするとエラーが生じてコンパイルできませんでした.

// test0.inc内
namespace ns {
    const bool bool_hoge = json_reader("filename.json");    // json_reader("ファイル名")はjsonファイルを読み取る関数
}

// test1.inc内
namespace ns2 {
    constexpr int i = [](){
        int num = 1;
        if( ns::bool_hoge ) num = 2;
        return num;
    }();
}

// main.cpp内 
#include "test0.inc"
#include "test1,inc"
int main() {
    std::cout << i << std::endl;
    return 0;
}
エラー内容は以下の通りです.
in ‘constexpr’ expansion of ‘<lambda closure object>ns2::<lambda()>{}.ns2::<lambda()>()’
エラー: the value of ‘ns::bool_hoge’ is not usable in a constant expression
 }();
   ^


比較用として,string型の変数に対してはラムダ式で以下のように記述しています. (こちらのみの場合はコンパイルが通って実行可能となりました.)

test1.inc
namespace ns2 {
    string str = [](){
        string name = "hoge1";
        if( ns::bool_hoge )  name = "hoge2";
        return name;
    }();
}

まだまだ勉強中で,ラムダ式の使用方法についても見よう見まねでトライしている最中です.何卒ご教示いただければ幸いです.

0

1Answer

エラー内容は ns::bool_hoge が定数ではないことを述べています。 定数であれば問題なく通るはずです。

namespace ns {
constexpr bool bool_hoge = 1;
}

namespace ns2 {
constexpr int i = ([]() {
    int num = 1;
    if (ns::bool_hoge) num = 2;
    return num;
})();
}

int main(void) {
    constexpr auto foo = ns2::i;
}

定数式の結果はコンパイル時に定数になるまで評価が可能なものなので、その中で分岐に使う値も当然にコンパイル時に確定しなければなりません。


質問に書くコードはなるべくコンパイル可能な全てを提示してください。 まだ、 C++ は規格の改定もあるので想定する規格の版を提示してください。

今回はエラーメッセージから察することが出来ましたが ns::bool_hoge の定義が書かれていないのでそこにどのような問題があるのか適切な指摘が出来ない可能性がありました。

また、ラムダ式が constexpr の文脈で使えるようになったのは C++17 からですので、それ以前では根本的に不可能でした。

0Like

Comments

  1. @BenBecky

    Questioner

    閲覧・ご回答ありがとうございました.
    ご指摘いただいた点を質問本文に反映させていただきました.(コードについては全文の記載は不可能なので該当部分及び使用する変数の部分のみ抜粋しています.)
    ns::bool_hogeをconst boolとして定義しまっていました.このbool_hogeには,別の関数でjsonファイルから読み取った値を代入するようにしているため,constexpr bool型で定義するのは厳しそうです.
    また,C++98での実装のため,最後に記載いただいたように不可能な記述を試みているのではないかと考えています.
  2. C++98 だと constexpr やラムダ式がそもそも存在しないので細かな条件が関係なく不可能ですね。 const でも条件が揃えば定数になるルールは存在する (C++98 でも) のですが計算元になる値がコンパイル時にわからないならどうしようもないです。

Your answer might help someone💌