17

私はpluralsightC++コースをフォローしており、その中には次のコードがあります。

#include <iostream>

template <class T>
T max(T& t1, T& t2)
{
    return t1 < t2 ? t2 : t1;
}

int main()
{
    std::cout << "Max of 33 and 44 is " << max(33, 44) << std::endl;

    return 0;
}

このコードを入力しましたが、コースのコードとは異なり、エラーメッセージが表示されます。

C2664: 'max' : cannot convert parameter 1 from 'int' to 'int &'

コースのコードはVisualStudioExpress 2010で記述されていますが、私のコードはVisual StudioUltimate2010で記述されています。


編集

答えを提供し、すべてを片付けてくれたすべての人(ケイト・グレゴリー自身でさえ)に感謝します。

4

7 に答える 7

33

リテラル (および一般的な右辺値) は非 const 参照で渡すことができないため (呼び出し先がそれらを変更できる場合は意味がないため)。値渡しまたは const 参照のいずれかで渡します。

template <class T>
T max(const T& t1, const T& t2)
{
    return t1 < t2 ? t2 : t1;
}

また

template <class T>
T max(T t1, T t2)
{
    return t1 < t2 ? t2 : t1;
}
于 2012-11-25T21:16:49.727 に答える
4

33と44はどちらも右辺値です。それらは、参照ではなく値によって関数に渡されます。コンパイラは、これら2つを期待される型に変換できませんint &。参照で渡すことができる変数(左辺値)を使用します。

int a = 33, b = 44;

max(a, b); // 44

ここでは基本的な型を扱っているだけなので(int)、参照による受け渡しは冗長です。値を渡すとコピーが発生しますが、違いはごくわずかです。

template <class T>
T max(T t1, T t2);

ここでは、右辺値と左辺値の両方を渡すことができます。ただし、クラス型のオブジェクトを渡すことができる可能性がありますその場合、参照渡しをお勧めします。

ただし、コピーが不要で、左辺値と右辺値の両方が必要な場合は、const参照で渡すことができます。

template <class T>
T max(T const &t1, T const &t2);

C ++ 11では、glvaluesをバインドできるように、ユニバーサル参照で引数を渡すことができます。

template <class T>
T max(T&& t1, T&& t2);

int main()
{
    int a{0}, b{0};

    max(a, b);
    max(1, 2);
}

元のコードで左辺値参照構文を保持したい場合は、次の左辺値シムを使用できます。

template<typename T>
T& lvalue(T&& t)
{
    return t;
}

int main()
{
    max(lvalue(1), lvalue(2));
}
于 2012-11-25T21:16:38.417 に答える
4

ここでの答えは、テストで使用しなかった無関係なコードにあることがわかりました。絶対に私の小さな max() は、値または const-ref のいずれかを取る必要があります。

しかし、完全なデモ コードは見事に動作します。これは、より多くのヘッダーが含まれているためです。そのうちの 1 つは xutility をもたらしますstd::max。これにより、自分のが使用されていないことに気付かmaxなくなりました。biggestそのようなことが起こらないように、デモを名前を付けてやり直します。それまでの間、はい、リテラルを参照によって関数に渡したい場合は、const ref である必要があります。私はそれを知っていましたが、テスト ハーネスを書いている間は考えもしませんでした。コードをもっと注意深く読み直すべきでした。これについて注意を喚起してくれてありがとう。(コースを受講していただきありがとうございます。お役に立てば幸いです。)

于 2012-11-25T21:54:04.870 に答える
3

一時的な値をとして渡すことはできませんT&。引数は変更しないので、const T&代わりに使用してください

ところで、組み込みmax機能があります

于 2012-11-25T21:16:25.187 に答える
3

整数リテラルは非 const 参照として渡すことはできません。さらに、max関数はconst参照を使用できるため、適切にマークします。

T max(const T& t1, const T& t2)
于 2012-11-25T21:17:39.220 に答える
2

参照によってパラメーターを使用して関数を定義した場合、そのパラメーターには変数名以外は使用できません。そして、数値を使用しようとします。

于 2012-11-25T21:16:25.127 に答える
2

ちょっと一言。関数「 max 」の初期コードを使用できます。通話を からmax(34, 44)に変更してみてくださいmax<const int>(34,44)。役に立つ場合もあります。

#include <iostream>

template <class T>
T max(T& t1, T& t2)
{
   return t1 < t2 ? t2 : t1;
}
int main()
{
   std::cout << "Max of 33 and 44 is " << max<const int>(33, 44) << std::endl;
   return 0;
}
于 2012-11-28T05:15:07.037 に答える