0

左辺値と右辺値の両方の参照を受け入れる関数を呼び出すための解決策を探しているときに、次のコードを書きました (いいえ、二度とやりません、約束します)。

目標は、左辺値と右辺値の両方の参照を受け入れる関数を提供することでした。2 つの関数を記述したり、呼び出し側で左辺値/右辺値を気にしたりしたくありませんでした。したがって、l/rvalue (この場合は get_addr) であるかどうかに関係なく渡すことができるように、パラメーターをラップするマクロ/関数を提供することを考えました。

関数に渡されたデータを変更したい場合はありません。

template<typename T>
std::shared_ptr<T> get_addr(T t) {
    std::shared_ptr<T> p(new T(t));
    return p;
}

int get_value(int x){
    return x * 2;
}

void print_value(int* p){
    cout << *p << endl;
}

int main() {
    print_value(get_addr(get_value(42)).get());
}

そのコードは私にとっては問題なく機能していますが、安全であるとは思えません。私の推測: get() を shared_ptr から呼び出した後、 get_value() の結果は不要になり、却下される可能性があります。そのため、print_value は無効な参照を受け取る可能性があります。それは理にかなっていますか?いずれにせよ、提供されたコードが好きではありません。一時変数を使用して問題を解決しました。

それにもかかわらず、その問題に対するより良い解決策があったかどうか、私はまだ興味があります. 構文の観点から、l/rvalue の両方を受け入れる関数「void print_value(int&& p)」を 1 つだけ使用することをお勧めします。移動セマンティクス、l/rvalue 変換を見てきましたが、本当に見栄えのする解決策が見つかりませんでした。

4

2 に答える 2

4

関数に渡されたデータを変更したい場合はありません。

では、これの何が問題なのですか?

void print_value(int p){
    cout << p << endl;
}

または、高価なタイプをコピーしたくない場合は、次のようにします。

void print_value(T const& p){
    cout << p << endl;
}
于 2012-03-06T13:31:37.037 に答える
2

まず、をとることができconst T&、l値とr値の両方にバインドされます。ただし、より直接的には、「パーフェクトフォワーディング」がこの問題の解決策です。

于 2012-03-06T13:32:40.173 に答える