2017-02-12 16 views
0

私は変更したくない構造体型を渡すプログラムを書いています。この構造体には2人のconstメンバーを持ち、次のようになります。エラー:const型のユニット化されたメンバC++

struct system_s { 
    std::string name; 
    std::string pkg; 
    char *const start_cmd[10]; 
    char *const end_cmd[10]; 
    bool ros; 

    bool equals(const system_s &cmp); 
}; 

構造体は、次の形式でマップに格納されています。

std::map<std::string, system_s> sys_map;

別の一時的なマップがあります:それは、クラスのメンバーです。必要に応じてsys_mapをキャッシュと考えてください。しかし、実際には、この質問のためにどのように使用されているか心配する必要はありません。 sys_mapは、次のように一時マップにシステムを追加するために呼び出されています。これは、クラスメソッドである:

add_system(sys_map[msg->system]);(*)

この関数は次のように定義されています。これは、クラスメソッドである:

int add_system(const system_s &sys);

と呼ばれている(*)は、私は次のエラーを取得するとき:

system.h: In instantiation of ?std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = system_s; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, system_s> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = system_s; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]?: 
/tc_manager_node.cpp:74:41: required from here 
/system.h:26:8: error: uninitialized member ?system_s::start_cmd? with ?const? type ?char* const [10]? [-fpermissive] 
struct system_s { 
     ^
system.h:26:8: error: uninitialized member ?system_s::end_cmd? with ?const? type ?char* const [10]? [-fpermissive] 
In file included from /usr/include/c++/4.8/map:61:0, 
       from /opt/ros/indigo/include/ros/console.h:42, 
       from /opt/ros/indigo/include/ros/ros.h:40, 
       from 

/tc_manager_node.cpp:2: は/ usr /含める/ C++/4.8/bits/stl_map.h:469:59:note:合成メソッド?system_s :: system_s()?最初に必要です __i = insert(__ i、value_type(__ k、mapped_type()));

このメンバーはなぜsystem_sのメンバーが初期化されていないのですか?すでに格納されているのはおそらくsys_mapに初期化されています。それはint add_system(const system_s &sys)の参照としてsystem_sを渡すことと関係がありますか?

+2

'const'クラスのメンバは、オブジェクトの構築中に初期化する必要があります。 'start_cmd'と' end_cmd'は初期化されていません。 –

+0

どの可変型を 'char * const *'にキャストできますか?私はそのキャストに問題があります。 – errolflynn

+1

'char * const *'を –

答えて

1

operator[]map(これはsys_map[msg->system]と呼ばれます)は、マップエントリが見つからない場合に新しいエントリを作成する可能性があります。新しいエントリはデフォルトで構築されますが、あなたのクラスはデフォルトで構成可能ではありません。

これを修正するには、[]を地図上に使用しないでください。代わりにfindを使用して、探しているエントリを見つけてください。

+0

うわー、うまくいった!それを 'sys_map.find(msg-> system) - > second'に変更しました。後でこの非効率性を修正する必要がありますが、それはピンチで動作します。ありがとう友人 – errolflynn

+1

@errolflynn念頭に置いておいてください。通常のイディオムは 'auto item = sys_map.find(bla); if(item!= sys_map.end()){...何かをitem-> second ...}で実行する ' –

+0

このプログラムの特定の部分は、C++ 03のフレームワーク内でのみサポートされています。方法はわかりません。私が正しいとすれば、 'auto'キーワードは変数の保存期間と関係しています。しかし、はい、私は確かにそれを行うためにstd :: map :: iteratorアイテムタイプを使用することができます。 – errolflynn

1

@Greg Kikola氏によると、constメンバーと初期化する必要があります。

+0

私の前提は、私は実際に 'constポインタ'を初期化せずに変数を初期化しようとしました。 'struct'変数が参照として渡されるので、そのコードではコンストラクタを私の知識に呼ぶべきではありません。それは、私は明らかに間違っていると言われています。私が抱えている問題は 'char * const *'型へのキャストです。どのような型をコンストラクタに渡すことができますか? – errolflynn

+0

参照として渡す場合でも、それを構築する必要があります。 – Gambit

+0

@ M.Mの答えを参照してください。 – errolflynn

1

ポインタ付きのconstの位置は、時には混乱することがあります。これは、初期化子リストを使用してその方法を確認してください(std::initializer_listと混同しないでください)。 X * const pを示し:

“p is a const pointer to an X that is non- const ”: you can’t change the pointer p itself, but you can change the X object via p. [source]

これはsystem_sを使用して作成されたアドレスを変更することはできませんことを意味します。 start_cmdまたはend_cmdを初期化するコンストラクタではないので、これは悪いことです。これは、10個のポインタのどれにも有効なアドレスを割り当てることができないことを意味します。初期化されていないアドレスから始まり、決して他のものに割り当てられることはありません。

編集: この投稿はタグ付きです: C++ 03で配列を初期化する方法はありません。この問題をいくつかの回避策で見ることができます:Initializing a member array in constructor initializerと一緒に行く能力があれば、List Initializationを使用できます。

+0

'start_cmd'と' end_cmd'を初期化するのにコンストラクタを使用できますか?もしそうなら、コンストラクタ内のどのタイプが初期化(好ましくは初期化リストで)を実行するのに適していますか?これらは 'system()'や 'exec()'呼び出しに渡されるコマンドです。 – errolflynn

+1

@errolflynn私は編集しました。しかし、コンストラクタの初期化リストで配列を初期化する単純な方法はありません。[tag:C++ 11]いくつかの回避策を含むリンクが含まれています。最も簡単なことは、確かに 'start_cmd'と' end_cmd'を非constにすることです。 –

+0

ありがとうございます。おそらくもっと簡単かもしれませんが、私はすでにこのメソッドを使用し始めているので、このメソッドを使用することができます。 'start_cmd'と' end_cmd'変数は、 'exec'呼び出しのために使用される可能性があります。これが、それらの型付けの理由です。 – errolflynn

関連する問題