3

私はを頂きたい

template <class T>
void foo(T &t);

参照によって他のオブジェクトを受け入れ、それらの非 const メソッドを呼び出すことに妥協することなく、一時オブジェクトも受け入れることができるようにします。C++03 で可能ですか?

オブジェクトのすべてのメソッドを として宣言しconst、すべてのメンバーを として宣言し、参照mutableを使用するようユーザーに強制できる可能性があることはわかっていますconst T &tが、それは醜い回避策です。

4

3 に答える 3

4

C++03 では、関数に渡された引数が左辺値か右辺値かを推測する方法がありません。

これが、質問のタイトルに「一時値を値で受け入れる」と書かれている理由だと思います。そのようなメカニズムが存在する場合、その情報に基づいて、パラメーターの型をT&orにするかどうかを決定する関数 (テンプレート) を作成できます。T

これはまさに、C++11 でサポートされている型推定機構が行うことです。

template<typename T>
void foo(T&& t);
//       ^^^
//       lvalue of type A is passed: T = A&, signature = foo(A& t)
//       rvalue of type A is passed: T = A, signature = foo(A&& t)

しかし、前述のように、C++03 では式の値カテゴリを決定する方法がないため、これは正確には不可能です。

あなたが言及する可能性(すべてのオブジェクトにconstメンバー関数を強制する)は回避策ではありません(醜いものでさえありません):メンバー関数が all の場合、その入力の状​​態を変更する必要がないconstことを意味します。これは、問題が解決されるfoo()可能性があることを意味します。const&

オブジェクトの状態を変更するために、これらのconstメンバー関数に a を実行させるつもりだったのかもしれませんが、 の内部でも同じことができます。これが悪い考えである理由は、どちらの場合も、型が修飾されているオブジェクトに入力を与えることができず、これが当てはまるかどうかわからない可能性があるためです。const_cast<>foo()foo()const

于 2013-03-14T17:21:12.227 に答える
1

const 型参照を受け取り、非 const 型参照のコピーを作成する 2 番目の関数を作成できます。

template <class T>
void foo (T &t);

template <class T>
void foo (const T &x) {
    T copy(x);
    foo(copy);
}

デモンストレーションはこちらでご覧いただけます

この手法には、一時オブジェクトと実際のオブジェクトを区別できないという制限がありconstます。この結果、オリジナルfoo()はオブジェクトを渡すことができなくなりconstます。この提案はそれらを許可するため、最初に提供された安全性がいくらか失われます。const 型バージョンの名前foofoo_for_temp. そうすれば、呼び出し元は関数の意図を知ることができます。

于 2013-03-14T17:19:17.210 に答える
0

危険な解決策の 1 つは、const T & を関数の引数として使用し、次に const_cast<> を T& に指定することです。定義されていない動作を簡単に引き起こす可能性があるため、関数に渡すものに注意する必要があります。

template <class T>
void foo(const T &ct)
{
    T &t = const_cast<T>( ct );
    // ...
}
于 2013-03-14T17:07:46.453 に答える