2017-09-29 13 views
0

私はconstというメンバ変数を持っている状況がありますが、いくつかの制御パスではアクセスできないことがあります。このような場合、オブジェクトを構築するときに、そのメンバを初期化する時間を無駄にしたくありません。`const`メンバを空にする方法


は、以下の玩具例を考えてみてください。私はint const val;int val;を変更した場合、しかし、

function():       # @function() 
     ret 

struct Foo { 
    int val; 
    Foo() {} 
}; 
auto function() { return Foo(); } 

これは、所望のアセンブリ(クラン5.0.0 -O3)を生成しますコンパイルが失敗します(constメンバを初期化する必要があるため):

struct Foo { 
    int const val; 
    Foo() {} //<- Fails! `const` members must be initialized. 
}; 

どのように私は、しかし、任意の実行時のコストをかけることなく、int const val;を初期化することができますか?例:上記の例では、マークされた行をどのように修正する必要がありますか?


注:デフォルトの初期化valこのvalをゼロに初期化するので(すなわち、Foo() : val() {}またはFoo() = default;を使用して)、ない許容です:

function():       # @function() 
     xor  eax, eax 
     ret 
+0

「xor eax、eax」が受け入れられない状況にありますか?もしそうなら、その状況はどういうものでしょうか? –

+1

穏やかで貧弱な 'int'の場合、前述の' int'を初期化しないことから利得を測定するために、世界で最も正確な原子時計を使う必要があります。ゼロを初期化してから、より重要な問題に移ります。より高価なオブジェクトの場合は、 'std :: optional'が有望な解決策になります。 –

+0

@NeilButterworth私が書いたように、これはおもちゃの例です。 IRL、 'val'は実際のオブジェクトかもしれません。その場合、オーバヘッドは任意に大きくなります。 – imallett

答えて

0

あなたが最初かどうかの質問をする必要がありますこれが可能であり、そうであればどのように。

この場合、答えはで、です。これは、クラスのconstデータメンバーを自分で、またはデフォルトの初期化値で初期化する必要があるためです。


PS:変数を初期化することは、時間に関して相対的に安いので、これは早すぎる最適化の古典的なケースである必要があります。

0

int型の場合、時間を節約することはできません。 もっと複雑な場合は、std::optional<T>を使用してください。初期化されているかどうかを問い合わせることができます。メモリにオーバーヘッドが1ビットしかなく、実行時にゼロになります(空でないことが分かっている場合は逆参照は不要です)。 if)。

extern bool ShouldInit; 

struct Foo { 
    std::optional<MyExpensiveType> oMyStuff_; 
    Foo() 
     : oMyStuff(ShouldInit ? make_optional<MyExpensiveType>() 
           : std::nullopt) {} 
    int fn() 
    { 
     return oMyStuff_ ? *oMyStuff_ 
          : 0; 
    } 
}; 
関連する問題