1

この質問のタイトルを検索すると、同じエラーを引用する多くの人がいますが、状況は異なります。残念ながら、そこに提供される回答は彼らの状況に固有のものであり、彼らがどのように私を助けることができるかわかりません。

operator<<テンプレートクラスをオーバーロードしようとしています。以下はテストケースです。

Vector.h:

#ifndef __INCL_VECTOR_H__
#define __INCL_VECTOR_H__

#include <array>

template < class T, unsigned int N >
class Vector
{
public:
    Vector();
    Vector( std::array< T, N > );

    template < class U, unsigned int M > friend Vector< U, M > operator+ ( const Vector< U, M >&, const Vector< U, M >& );

    template < class U, unsigned int M > friend std::ostream& operator<< ( std::ostream&, Vector< U, M >& );

    T& operator[] ( const unsigned int& );

protected:
    std::array< T, N > _values;
};

#include "Vector.hpp"

#endif

Vector.hpp:

#include "Vector.h"
#include <iostream>

template < class T, unsigned int N >
Vector< T, N >::Vector()
{
}

template < class T, unsigned int N >
Vector< T, N >::Vector( std::array< T, N > otherArray )
{
    _values = *( new std::array< T, N >( otherArray ) );
}

template < class U, unsigned int M >
Vector< U, M > operator+ ( const Vector< U, M > &lhVector, const Vector< U, M > &rhVector )
{
    Vector< U, M > sumVector;

    for( unsigned int i = 0; i < M; i++ )
        sumVector[i] = lhVector[i] + rhVector[i];

    return sumVector;
}

template < class U, unsigned int M >
std::ostream& operator<< ( std::ostream &out, Vector< U, M > &cVector )
{
    out << "< ";

    for( int i = M - 1; i >= 0; i-- )
    {
        out << cVector[i];
        if( i )
            out << ", ";
    }

    out << " >";

    return out;
}

template < class T, unsigned int N >
T& Vector< T, N >::operator[] ( const unsigned int &index )
{
    return _values[ index ];
}

vectorTest.cpp:

#include "Vector.h"

#include <iostream>
#include <array>

using namespace std;

int main( int argc, char* argv[] )
{
    Vector< int, 3 > u( array< int, 3 > {  1, 4,  2 } );
    Vector< int, 3 > v( array< int, 3 > { -2, 3, -1 } );

    cout << "u = " << u << endl;
    cout << "v = " << v << endl;
    cout << "u + v = " << u + v << endl;

    return 0;
}

エラーの原因となる行はcout << "u + v = " << u + v << endl;;です。前の2行は期待どおりに機能します。

エラーメッセージは次のとおりです(としてコンパイルg++ -std=c++11 Vector.h vectorTest.cpp):

vectorTest.cpp: In function ‘int main(int, char**)’:
vectorTest.cpp:15:31: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from Vector.hpp:2,
                 from Vector.h:34:
/usr/include/c++/4.7/ostream:600:5: error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Vector<int, 3u>]’
In file included from Vector.h:34:0:
Vector.hpp: In instantiation of ‘Vector<U, M> operator+(const Vector<U, M>&, const Vector<U, M>&) [with U = int; unsigned int M = 3u]’:
vectorTest.cpp:15:31:   required from here
Vector.hpp:40:9: error: passing ‘const Vector<int, 3u>’ as ‘this’ argument of ‘T& Vector<T, N>::operator[](const unsigned int&) [with T = int; unsigned int N = 3u]’ discards qualifiers [-fpermissive]
Vector.hpp:40:9: error: passing ‘const Vector<int, 3u>’ as ‘this’ argument of ‘T& Vector<T, N>::operator[](const unsigned int&) [with T = int; unsigned int N = 3u]’ discards qualifiers [-fpermissive]

これらのエラーメッセージが何を示しているのか理解できません。何か助けていただければ幸いです。

4

2 に答える 2

6

最初の問題:

プログラムをコンパイルするにはconst、の2番目のパラメーターとして( -declarationとその関数の定義のoperator <<両方で)への左辺値参照を使用します。friend

template < class U, unsigned int M >
std::ostream& operator<< ( std::ostream &out, Vector< U, M > const& cVector )
//                                                           ^^^^^

プログラムがコンパイルされない理由は、のオーバーロードが2番目の引数としてoperator <<non-への左辺値参照を受け入れ、non-への左辺値参照が右辺値にバインドできないためです。constconst

operator +の2つのインスタンス間の結果はVector一時的なものであり、一時的なものは右辺値であるため、コンパイラはを呼び出すことができずoperator <<、したがって呼び出しを解決できません。

2番目の問題:

上記の問題を修正したら、2番目の問題を解決する必要があります。クラステンプレートはのバージョンをVector提供しないため、ベクトルへの参照を受け入れるように書き換えられたは、ベクトルの要素にアクセスできなくなります。 。constoperator []operator <<const

template < class T, unsigned int N >
class Vector
{
    // ...

    T& operator[] ( const unsigned int& );

    T const& operator[] ( const unsigned int& ) const; // <== ADD THIS!

    // ...
};

そしてもちろん、対応する定義:

template < class T, unsigned int N >
T const& Vector< T, N >::operator[] ( const unsigned int &index ) const
{
    return _values[ index ];
}
于 2013-03-25T21:29:15.217 に答える
3

これを変える:

std::ostream& operator<< ( std::ostream&, Vector< U, M >& );

これに:

std::ostream& operator<< ( std::ostream&, const Vector< U, M >& );
//                                        ^^^^^

コンパイラは、C++では非constVectorなどの一時的なものu + vをバインドできないと言っています。 Vector&

そして、あなたはそれを変更しないVectorので、それは最初からあるべきですconst

于 2013-03-25T21:27:47.000 に答える