5

Forwarding Reference (以前はScott Meyers によってUniversal Referencesと呼ばれていました) のデフォルト引数を指定する方法を理解するのに苦労しています。

私がやりたいことをしようとしているコードの例を次に示します。

struct encoder_t {

} const encoder = {};

struct validator_t {

} const validator = {};

struct test {

    template <typename Range, typename Encoding, typename Validation>
    test ( Range&& range, Encoding&& encoding = encoder, Validation&& validation = validator ) {

    }

};

int main() {

    test( "woof" );

}

Coliru でも利用できます

エラーを調べてみると、テンプレート引数をデフォルトに設定し、その後引数をデフォルト構築することで機能させることができることがわかりました。

// Works! But the syntax is strange... potential ramifications/deduction mishaps?
// Is this the "proper" way to default these arguments?
template <typename Range, typename Encoding = encoder_t, typename Validation = validator_t>
test ( Range&& range, Encoding&& encoding = Encoding(), Validation&& validation = Validation() ) {

}

コリルにも

これはこれを処理する「適切な」方法ですか?私が使用する構文は何ですか?「デフォルトの転送参照」の望ましい効果を得る方法は複数ありますか? これはどのように書けばよいのでしょうか?また、後でコードに大量の SFINAE を振りかけることになるので、複数のオーバーロードの記述を含まないものをはるかに好むことを覚えておいてください。

4

1 に答える 1

3

まず第一に、デフォルトの引数からテンプレートの型を推測することはできません。したがって、オプションで転送参照に一致する引数を指定できるという考えを実現する他の方法を探すことしかできません。

この回避策は、次のことを示唆しています。

template <typename Range, typename Encoding = encoder_t, typename Validation = validator_t>
test ( Range&& range, Encoding&& encoding = encoder, Validation&& validation = validator )
{
}

ただし、これは失敗します。転送参照は、テンプレート タイプを参照タイプとして推測することによって機能しますが、オブジェクト タイプが指定されています。右辺値参照は、ダミー オブジェクトの左辺値にバインドできなくなりました。

投稿で述べているように、デフォルトをencoder_t{}ダミー オブジェクトではなく一時オブジェクトにすることで、これを修正できます。この質問は、その場合、参照が転送参照のままであることを確認します。

もう 1 つの回避策は、デフォルトの引数の代わりに別のコンストラクターを使用することです。

template <typename Range>
test ( Range&& range )
{
}

template <typename Range, typename Encoding>
test ( Range&& range, Encoding&& encoding )
{
}

template <typename Range, typename Encoding, typename Validation>
test ( Range&& range, Encoding&& encoding, Validation&& validation )
{
}

コンストラクター本体で行う内容によっては、コンストラクター委任を使用してこれを実装できます。

SFINAE を追加する意図について言及しているため、この投稿にはいくつかのアイデアがあるかもしれません:コンストラクターでユニバーサル参照を使用するときにデフォルトの構築を許可する方法

于 2014-11-27T02:24:29.497 に答える