4

関数では、左辺値と右辺値の参照を区別する必要があるため、明らかなパスはオーバーロードすることです。

void myfunc(A&& a);
void myfunc(const A& a);

これは、適切に定義された型と暗黙の変換を備えた、まさに望ましい動作をしています。ただし、コードの重複が多すぎるため、関連する決定を内部にカプセル化し、単一の関数のみを保持することを希望するため、ユニバーサル参照による受け渡しがオプションになる場合があります。

template <typename A>  void myfunc(A&& a);

ただし、これには不幸な欠点があり、現在は任意のオブジェクトを最初のパラメーターとして渡すことができるため、enable_if を介して制約を課すことができます。

template <typename T, class  = typename enable_if<
    is_same<typename remove_const<typename    remove_reference<T>::type>::type, A>::value,
    T>::type>   
void myfunc( T&&  a);

これはほとんど仕事をしているように見えますが、(すでにテンプレート化していると思います) 暗黙的な変換コンストラクターを型 A (型 C パラメーターからなど) にトリガーできるオーバーロードの優れたプロパティを失いました。一部の関数には 3 つ以上の A&& パラメーターがあり、組み合わせの爆発を処理する意図がないため、オーバーロードはオプションではありません。暗黙の変換を何らかの方法で回復できますか? もちろん、回避策の 1 つは、たとえば、A に許可されている他のパラメーター型を追加し、メイン関数で必要な変換を実行することです。それでも変換によって右辺値を生成します)。もっと良い方法はありますか?

4

1 に答える 1

5

これが存在する理由std::is_convertibleです:

template <typename T, 
          class = typename enable_if<is_convertible<T, A>::value>::type>   
void myfunc( T&&  a);
于 2016-02-15T14:00:29.537 に答える