2016-11-17 6 views
1

私は興味があります。私は署名const&parameterから&parameterへの無効な変換はナンセンスに見えますか?

CommandLogFilter::CommandLogFilter(QSharedPointer<LogServer> logServer, QObject *parent, 
         void (*preprocessValidCommand)(CommandDescriptor &descriptor)) 

とグラムからエラーを取得してコンストラクタの三番目のパラメータとして署名

void printCommandReceived(const CommandDescriptor &descriptor) 

と関数へのポインタを渡してい++コンパイラー:私の理解で

error: invalid conversion from ‘void (*)(const CommandDescriptor&)’ to ‘void (*)(CommandDescriptor&)’ [-fpermissive] 

以外への参照-constオブジェクトは、constオブジェクトのパラメータを参照するための引数として使用可能である必要があります。したがって、非constオブジェクト参照を受け入れる関数への型ポインタを持つパラメータは、constオブジェクト参照でさえも受け入れる関数へのポインタ型の引数よりも満足すべきであり(暗黙の変換を行わなければならない)

どこが間違っていますか?

+1

"何かへのポインタ"があり、 "他のものへのポインタ"を渡したいと思います。そのような場合は、ポイント先の型が似ている場合でも暗黙の変換はありません。 –

答えて

2

void (*)(const CommandDescriptor&)およびvoid (*)(CommandDescriptor&)は、2つの全く異なる、無関係のタイプである。

constに関する非常に単純なルールがあります。はX**X const * const *に変換し、その上ですることができ、X const*に変換することができます。参照と同じこと。他には何も許されない。

X**などの任意の位置にconstを任意に追加または削除することはできません。たとえば、X const **には変換できません。これは関数引数の位置についても当てはまります。互換性のある型を取得するためには、constを追加または削除できません。

あなたのようなケースに対応して一貫性を保つようにこれらのルールを拡張できますか?おそらくそう。しかし、彼らはそうではありません。

1

C++には暗黙的にconstを追加または削除できる限られた状況があります。あなたはそれができない場所に逃げました。そうでない理由は、「安全であるケースを説明するのは難しく、基準作成者は怠け者であり、控えめである」という単純なことでしょう。

回避策として、あなたはこれを行うことができます。

CommandLogFilter bob(
    logServer, 
    parent, 
    [](CommandDescriptor &descriptor) { 
    return printCommandReceived(descriptor); 
    } 
); 

としてステートレスラムダは、暗黙的に変換さ-にすることができますポインタ自分の署名を照合関数に。

署名をそこに明示する必要はありませんが、テンプレート "auto" lambdasと似たようなことをする方法はありません。残念なことにその署名が推測されます。

関連する問題