2

初心者の質問で申し訳ありませんが、C++についてはよくわかりません。次のコードをコンパイルするときに、「エラー:コンストラクターの呼び出しは定数式に表示されません」というエラーが発生する理由を誰かが答えることができますか。

class EliminationWeight
{
 public:
    typedef double Type;
    static const Type MAX_VALUE = __DBL_MAX__;
    static const Type MIN_VALUE = -__DBL_MAX__;
};

私はUbuntu12.04とそれに付属するgccを使用しています。これは私のコードではなく、このコードはおそらく100%正常に機能することを知っています(おそらく古いバージョンのgccまたは他のコンパイラで)。それを修正する簡単な方法はありますか?

よろしくお願いします。SOで質問するのはこれが初めてです。

4

3 に答える 3

6

Call to a constructor cannot appear in a constant-expressionはGCCエラーメッセージですが、ここではあまり意味がありません。たとえば、Clangは、いくつかの警告とともにコードを受け入れます。

test.cpp:31:23: warning: in-class initializer for static data member of type
      'const Type' (aka 'const double') is a GNU extension [-Wgnu]
    static const Type MAX_VALUE = __DBL_MAX__;
                      ^           ~~~~~~~~~~~

とにかく、クラス本体でdoubleを初期化することは非標準です。個別に初期化を行う必要があります。

class EliminationWeight
{
 public:
    typedef double Type;
    static const Type MAX_VALUE;
    static const Type MIN_VALUE;
};

次に、1つのソースファイル(ヘッダーファイルではない)で:

const EliminationWeight::Type EliminationWeight::MAX_VALUE = __DBL_MAX__;
const EliminationWeight::Type EliminationWeight::MIN_VALUE = -__DBL_MAX__;

一般に、初期化できるのは、クラス本体に整数型を持つ静的メンバー変数のみですが、これはC++0x11で拡張されています。C++でのクラス宣言内でのconstメンバーの初期化も参照してください。

于 2012-07-03T22:49:25.173 に答える
2

私はこのまったく同じ問題に出くわしました。ここで説明しているコードは、KITによる収縮階層の実装の一部です。

これは、gcc4.8でコードをコンパイルしようとしたときに発生する唯一のコンパイルエラーです。

@vitautによって提案された修正は、これを機能させるために必要なものです。ただし、main.cppにはすでに次の行が残っていることに注意してください。

// doesn't look nice, but required by the compiler (gcc 4)
...
const EliminationWeight::Type EliminationWeight::MAX_VALUE;
const EliminationWeight::Type EliminationWeight::MIN_VALUE;

EliminationWeight.hと一緒にEliminationWeight.cppファイルを作成し、それをMakefileに含めることにした場合、これらの行が上記とは異なるエラーを表示する理由です。

main.cpp:86:31: error: uninitialized const ‘EliminationWeight::MAX_VALUE’ [-fpermissive]
 const EliminationWeight::Type EliminationWeight::MAX_VALUE;
                               ^
main.cpp:87:31: error: uninitialized const ‘EliminationWeight::MIN_VALUE’ [-fpermissive]
 const EliminationWeight::Type EliminationWeight::MIN_VALUE;
                               ^

解決策は、main.cppでこれらの行を削除するか、実際の初期化に使用することです。私は後者を使用しましたが、行は次のようになります。

const EliminationWeight::Type EliminationWeight::MAX_VALUE = std::numeric_limits< EliminationWeight::Type >::max();
const EliminationWeight::Type EliminationWeight::MIN_VALUE = -std::numeric_limits< EliminationWeight::Type >::max();

typedefstd::numeric_limitsで定義されたタイプのテンプレートを使用したことに注意してください。EliminationWeight::Typeこれは、別のタイプを使用するためにそのtypedefを変更するだけでよいことを意味します。

ただし、main.cppでこれらを使用するには、numeric_limitsテンプレートのヘッダーを含める必要があります。ヘッダーを含めなくても機能しましたが、他のインクルードファイルを介してインクルードされている可能性があります。クリーンなコードの目的のために、とにかくそれを含める必要があります。

#include <limits>

また、C ++ 11はテンプレートに新しい関数lowestを提供しますnumeric_limits。つまり、最後の行を次のように置き換えることができます。

const EliminationWeight::Type EliminationWeight::MIN_VALUE = std::numeric_limits< EliminationWeight::Type >::lowest();

ただし、のC ++リファレンスでlowestは、浮動小数点型の戻り値を次のように指定しています。

実装に依存します。一般的に、max()の負の値

ですから、この機能を使って多くの利益が得られるかどうかはわかりません。見た目がすっきりしたコードになりますが、戻り値は多少指定されていないようです。

于 2013-07-11T06:06:52.673 に答える
0

Timeクラス内のクラスの静的constオブジェクトを宣言してインスタンス化しようとしたときに、この問題が発生しましたAlg。これは、クラス内でメンバー変数を宣言し、次のように外部でインスタンス化すると機能しました。

Class Alg {

    public: 
    .
    .

    static const Time genTime;
    .
    .
}

const Alg::genTime = Time(0,0,1,0);
于 2014-08-19T21:03:45.513 に答える