2016-10-04 15 views
1

2つのtypenameパラメータを持つテンプレートメソッドがあります(実際にはQObject::connect() - this answeranother answerを参照)。型名はメンバポインタ用であるため、渡された名前がオーバーロードされた関数を参照すると、控除が失敗する可能性があります。そのような場合は、1つの引数を正しい型に強制したり(おそらく、それを目的の型のローカル変数に格納することによって)、あるいは1つ以上のテンプレートパラメータで呼び出しを修飾する必要があります。最初のテンプレートパラメータをデフォルトに設定できますか?

QObject::connect(spinBox, &QSpinBox::valueChanged, 
       slider, &QSlider::setValue); 

ニーズ(強制することによって)

QObject::connect<void(QSpinBox::*)(int)>(spinBox, &QSpinBox::valueChanged, 
             slider, &QSlider::setValue); 

やとして書き込まれる:時々

void(QSpinBox::*signal)(int) = &QSpinBox::valueChanged; 
QObject::connect(spinBox, signal, 
       slider, &QSlider::setValue); 

、ただし連結質問の一つから例に取る

最初のテンプレート引数は推定できますが、後のテンプレート引数が必要です。最初のパラメータをデフォルトにする簡単な方法はありますか?

QObject::connect<auto, void(QSpinBox::*)(int)>(slider, &QSlider::valueChanged, 
               spinBox, &QSpinBox::setValue); 

明らかに、それは有効なC++ではありませんが、私はそれがポイントを示すことを願っています。

私は

void(QSpinBox::*slot)(int) = &QSpinBox::setValue; 
QObject::connect(slider, &QSlider::valueChanged, 
       spinBox, slot); 

を書くことができます知っているが、私はより簡潔な構文のために願っています。

+0

私はあなたが静的キャストで必要なポインタ型に関数をキャストできるはずだと思います。 'static_cast (QSpinBox :: setValue)'のようなものです。テンプレート引数の控除が機能するようにして、型を指定する必要はありません。 – NathanOliver

+0

さて、それはさらに醜いです。私は、より安全な意味のある 'up_cast <>()'を定義することを好みます(狭くすることなく '?:'の引数を強制するのにも便利です)。 –

答えて

6

最初のパラメータをデフォルトにする簡単な方法はありますか?

QObject::connect(slider, &QSlider::valueChanged, 
    spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::setValue)); 

それともconnect()の異なるオーバーロードを使用し、ラムダ渡します:

QObject::connect(slider, &QSlider::valueChanged, 
    [&spinBox](int i){ spinBox.setValue(i); }); 

号は、あなただけのstatic_castと同じように、手動で第二引数を強制する必要があります

+0

答えはおそらく「いいえ」と思われましたが、質問する価値があるようでした。私はローカル変数アプローチをもっともクリーンなものにしていきます。 –

+0

@TobySpeightラムダアプローチのファンではありませんか? – Barry

+0

特に、それは主観的です。私はコードレビューでそれに反対しませんが、私はめったにそれを書いていません。おそらく、私はそのようなラムダが実際に発生するよりはるかにオーバーヘッドを想像している!接続タイプ引数を 'auto'から 'direct'に微妙に変更したので、ここで注意する必要があります。これはUI - > UI接続の問題ではありませんが、クロススレッドには問題があります。 –

関連する問題