2

奇妙な問題について助けを求めたい。マトリックスについてオンラインで入手したコードの場合、g++ でコンパイルして実行できますが、VC++ 2008 でのビルドに失敗します。vc++ からのビルド エラーは次のとおりです。

------ Build started: Project: Matrix, Configuration: Debug Win32 ------
Compiling...Matrix.cpp

c:\matrix\matrix\matrix.cpp(260) : warning C4996: 'std::inner_product': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'

c:\program files (x86)\microsoft visual studio 9.0\vc\include\numeric(103) : see    declaration of 'std::inner_product'
c:\matrix\matrix\matrix.cpp(275) : warning C4996: 'std::inner_product': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'

c:\program files (x86)\microsoft visual studio 9.0\vc\include\numeric(103) : see declaration of 'std::inner_product'

c:\matrix\matrix\matrix.cpp(288) : warning C4018: '<' : signed/unsigned mismatch

c:\matrix\matrix\matrix.cpp(290) : warning C4018: '<' : signed/unsigned mismatch

c:\matrix\matrix\matrix.cpp(346) : warning C4018: '<' : signed/unsigned mismatch

c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(1598) : error C2665: 'std::_Debug_range2' : none of the 2 overloads could convert all the argument types

c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(1577): 
    could be 'void std::_Debug_range2<_InIt>(_InIt,_InIt,const wchar_t *,unsigned 
    int,std::input_iterator_tag)'
    with
    [
        _InIt=Cslice_iter<double>
    ]
    c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(1583):      
    or       'void std::_Debug_range2<_InIt>(_RanIt,_RanIt,const wchar_t *,unsigned 
    int,std::random_access_iterator_tag)'
    with
    [
        _InIt=Cslice_iter<double>,
        _RanIt=Cslice_iter<double>
    ]
    while trying to match the argument list '(Cslice_iter<T>, Cslice_iter<T>, const wchar_t *, unsigned int, double)'
    with
    [
        T=double
    ]
    c:\program files (x86)\microsoft visual studio 9.0\vc\include\numeric(63) : see reference to function template instantiation 'void std::_Debug_range<_InIt1>(_InIt,_InIt,const wchar_t *,unsigned int)' being compiled
    with
    [
        _InIt1=Cslice_iter<double>,
        _InIt=Cslice_iter<double>
    ]
    c:\program files (x86)\microsoft visual studio 9.0\vc\include\numeric(106) : see reference to function template instantiation '_Ty std::_Inner_product<Cslice_iter<T>,_InIt2,_Ty,std::_Iter_random_helper<_Cat1,_Cat2>::_Iter_random_cat>(_InIt1,_InIt1,_InIt2,_Ty,_InItCats,std::_Range_checked_iterator_tag)' being compiled
    with
    [
        _Ty=double,
        T=double,
        _InIt2=double *,
        _Cat1=double,
        _Cat2=std::random_access_iterator_tag,
        _InIt1=Cslice_iter<double>,
        _InItCats=std::_Iter_random_helper<double,std::random_access_iterator_tag>::_Iter_random_cat
    ]
    c:\matrix\matrix\matrix.cpp(260) : see reference to function template instantiation 'double std::inner_product<Cslice_iter<T>,_Ty*,double>(_InIt1,_InIt1,_InIt2,_Ty)' being compiled
    with
    [
        T=double,
        _Ty=double,
        _InIt1=Cslice_iter<double>,
        _InIt2=double *
    ]
Build log was saved at "file://c:\Matrix\Matrix\Debug\BuildLog.htm"
Matrix - 1 error(s), 5 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

どんな助けでも本当に感謝しています。

どうもありがとう。

// Program to test slices and a simple N*M matrix class



#include<iostream>
#include<valarray>
#include<algorithm>
#include<numeric>   // for inner_product
using namespace std;

// forward declarations to allow friend declarations:
template<class T> class Slice_iter;
template<class T> bool operator==(const Slice_iter<T>&, const Slice_iter<T>&);
template<class T> bool operator!=(const Slice_iter<T>&, const Slice_iter<T>&);
template<class T> bool operator< (const Slice_iter<T>&, const Slice_iter<T>&);

template<class T> class Slice_iter {
valarray<T>* v;
slice s;
size_t curr;    // index of current element

T& ref(size_t i) const { return (*v)[s.start()+i*s.stride()]; }
public:
Slice_iter(valarray<T>* vv, slice ss) :v(vv), s(ss), curr(0) { }

Slice_iter end() const
{
    Slice_iter t = *this;
    t.curr = s.size();  // index of last-plus-one element
    return t;
}

Slice_iter& operator++() { curr++; return *this; }
Slice_iter operator++(int) { Slice_iter t = *this; curr++; return t; }

T& operator[](size_t i) { return ref(i); }      // C style subscript
T& operator()(size_t i) { return ref(i); }      // Fortran-style subscript
T& operator*() { return ref(curr); }            // current element

friend bool operator==<>(const Slice_iter& p, const Slice_iter& q);
friend bool operator!=<>(const Slice_iter& p, const Slice_iter& q);
friend bool operator< <>(const Slice_iter& p, const Slice_iter& q);

};


template<class T>
bool operator==(const Slice_iter<T>& p, const Slice_iter<T>& q)
{
return p.curr==q.curr
    && p.s.stride()==q.s.stride()
    && p.s.start()==q.s.start();
}

template<class T>
bool operator!=(const Slice_iter<T>& p, const Slice_iter<T>& q)
{
return !(p==q);
}

template<class T>
bool operator<(const Slice_iter<T>& p, const Slice_iter<T>& q)
{
return p.curr<q.curr
    && p.s.stride()==q.s.stride()
    && p.s.start()==q.s.start();
}


//-------------------------------------------------------------



// forward declarations to allow friend declarations:
template<class T> class Cslice_iter;
template<class T> bool operator==(const Cslice_iter<T>&, const Cslice_iter<T>&);
template<class T> bool operator!=(const Cslice_iter<T>&, const Cslice_iter<T>&);
template<class T> bool operator< (const Cslice_iter<T>&, const Cslice_iter<T>&);


template<class T> class Cslice_iter
{
valarray<T>* v;
slice s;
size_t curr; // index of current element
const T& ref(size_t i) const { return (*v)[s.start()+i*s.stride()]; }
public:
Cslice_iter(valarray<T>* vv, slice ss): v(vv), s(ss), curr(0){}
//typedef T        iterator_category; //I added these defs, otherwise more compile errors on vc++
//typedef T        value_type;        //after I uncomment these, build only fails at call inner_product     
//typedef T*       iterator;          //and transform calls.
//typedef const T* const_iterator;
//typedef T&       reference;
//typedef const T& const_reference;
//typedef T*       pointer;
//typedef std::size_t    size_type;
typedef std::ptrdiff_t difference_type;

Cslice_iter end() const
{
    Cslice_iter t = *this;
    t.curr = s.size(); // index of one plus last element
    return t;
}
Cslice_iter& operator++() { curr++; return *this; }
Cslice_iter operator++(int) { Cslice_iter t = *this; curr++; return t; }

const T& operator[](size_t i) const { return ref(i); }
const T& operator()(size_t i) const { return ref(i); }
const T& operator*() const { return ref(curr); }

friend bool operator==<>(const Cslice_iter& p, const Cslice_iter& q);
friend bool operator!=<>(const Cslice_iter& p, const Cslice_iter& q);
friend bool operator< <>(const Cslice_iter& p, const Cslice_iter& q);

};

template<class T>
bool operator==(const Cslice_iter<T>& p, const Cslice_iter<T>& q)
{
return p.curr==q.curr
    && p.s.stride()==q.s.stride()
    && p.s.start()==q.s.start();
}

template<class T>
bool operator!=(const Cslice_iter<T>& p, const Cslice_iter<T>& q)
{
return !(p==q);
}

template<class T>
bool operator<(const Cslice_iter<T>& p, const Cslice_iter<T>& q)
{
return p.curr<q.curr
    && p.s.stride()==q.s.stride()
    && p.s.start()==q.s.start();
}


//-------------------------------------------------------------


class Matrix {
valarray<double>* v;    // stores elements by column as described in 22.4.5
size_t d1, d2;  // d1 == number of columns, d2 == number of rows
public:
Matrix(size_t x, size_t y);     // note: no default constructor
Matrix(const Matrix&);
Matrix& operator=(const Matrix&);
~Matrix();

size_t size() const { return d1*d2; }
size_t dim1() const { return d1; }
size_t dim2() const { return d2; }

Slice_iter<double> row(size_t i);
Cslice_iter<double> row(size_t i) const;

Slice_iter<double> column(size_t i);
Cslice_iter<double> column(size_t i) const;

double& operator()(size_t x, size_t y); // Fortran-style subscripts
double operator()(size_t x, size_t y) const;

Slice_iter<double> operator()(size_t i) { return column(i); }
Cslice_iter<double> operator()(size_t i) const { return column(i); }

Slice_iter<double> operator[](size_t i) { return column(i); }// C-style subscript
Cslice_iter<double> operator[](size_t i) const { return column(i); }

Matrix& operator*=(double);

valarray<double>& array() { return *v; }
};


inline Slice_iter<double> Matrix::row(size_t i)
{
return Slice_iter<double>(v,slice(i,d1,d2));
}

inline Cslice_iter<double> Matrix::row(size_t i) const
{
return Cslice_iter<double>(v,slice(i,d1,d2));
}

inline Slice_iter<double> Matrix::column(size_t i)
{
return Slice_iter<double>(v,slice(i*d2,d2,1));
}

inline Cslice_iter<double> Matrix::column(size_t i) const
{
return Cslice_iter<double>(v,slice(i*d2,d2,1));
}

Matrix::Matrix(size_t x, size_t y)
{
// check that x and y are sensible
d1 = x;
d2 = y;
v = new valarray<double>(x*y);
}

Matrix::~Matrix()
{
delete v;
}

double& Matrix::operator()(size_t x, size_t y)
{
return column(x)[y];
}



//-------------------------------------------------------------




double mul(const Cslice_iter<double>& v1, const valarray<double>& v2)
{
double res = 0;
for (size_t i = 0; i<v2.size(); i++) res+= v1[i]*v2[i];
return res;
}


valarray<double> operator*(const Matrix& m, const valarray<double>& v)
{
if (m.dim1()!=v.size()) cerr << "wrong number of elements in m*v\n";

valarray<double> res(m.dim2());
for (size_t i = 0; i<m.dim2(); i++) res[i] = mul(m.row(i),v);
return res;
}


// alternative definition of m*v

//valarray<double> operator*(const Matrix& m, valarray<double>& v)
valarray<double> mul_mv(const Matrix& m, valarray<double>& v)
{
if (m.dim1()!=v.size()) cerr << "wrong number of elements in m*v\n";

valarray<double> res(m.dim2());

for (size_t i = 0; i<m.dim2(); i++) {
    const Cslice_iter<double>& ri = m.row(i);
    res[i] = inner_product(ri,ri.end(),&v[0],double(0));
}
return res;
}



valarray<double> operator*(valarray<double>& v, const Matrix& m)
{
if (v.size()!=m.dim2()) cerr << "wrong number of elements in v*m\n";

valarray<double> res(m.dim1());

for (size_t i = 0; i<m.dim1(); i++) {
    const Cslice_iter<double>& ci = m.column(i);
    res[i] = inner_product(ci,ci.end(),&v[0],double(0));
}
return res;
}

Matrix& Matrix::operator*=(double d)
{
(*v) *= d;
return *this;
}

ostream& operator<<(ostream& os, Matrix& m)
{
for(int y=0; y<m.dim2(); y++)
{
    for(int x=0; x<m.dim1(); x++)
        os<<m[x][y]<<"\t";
    os << "\n";
}
return os;
}


//-------------------------------------------------------------


void f (int x_max, int y_max)   // test layout and basic access
{
cout << "\nf(" << x_max <<"," << y_max << "):\n";

Matrix a(x_max, y_max);

for(int x=0; x<x_max; x++)      // initialize
    for(int y=0; y<y_max; y++)
        a[x][y]=x+y*10;

cout<<"C-style access used to initialize:\n" << a;

for(int x=0; x<x_max; x++)
    for(int y=0; y<y_max; y++)
        a(x,y)=x+y*10;

cout <<"Fortran-style access used to initialize:\n" << a;

cout << "addresses: \n";

for(int x=0; x<x_max; x++)
    for(int y=0; y<y_max; y++)
        cout<<"("<< x<<","<<y<<") at "<<&a[x][y]-&a[0][0]<<"\n";
cout <<"columns :\n";

for(int x=0; x<x_max; x++) {
    cout << "column " << x << ":\n";
    for (Slice_iter<double> c = a.column(x); c!=c.end(); ++c)
        cout << "\t" << *c <<"\n";
}

cout <<"rows :\n";

for(int y=0; y<y_max; y++) {
    cout << "row " << y << ":";
    for(Slice_iter<double> r = a.row(y); r!=r.end(); ++r)
        cout << "\t" << *r ;
    cout <<"\n";
}


}

ostream& operator<<(ostream& os, const valarray<double>& v)
{
for (int i = 0; i<v.size(); ++i) os << '\t' << v[i];
return os;
}

void g(int x_max,int y_max) // check multiplication
{
cout << "\ng(" << x_max <<"," << y_max << "):\n";

Matrix a(x_max,y_max);

for(int x=0; x<x_max; x++)      // initialize
    for(int y=0; y<y_max; y++)
        a[x][y]=x+y*10;

valarray<double> r(2,x_max);
cout << "a*v: " << a*r << endl;
cout << "m*v: " << mul_mv(a,r) << endl;

valarray<double> c(2,y_max);
cout << "v*a: " << c*a << endl;

}

int main()
{
f(3,4);
f(4,3);

g(3,4);
g(4,3);
}


//main for vc++
/*int _tmain(int argc, _TCHAR* argv[])
{
f(3,4);
f(4,3);

g(3,4);
g(4,3);

return 0;
}*/

// the stdafx.h from vc++
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

/*#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
*/
4

1 に答える 1

0

ライブラリは、適切に動作するイテレータに含まれる必要があるネストされた typedef を探すことによって、イテレータが input_iterator か random_access_iterator かを調べようとしていると思います。具体的にはiterator_category

std::iterator標準では、適切な定義を取得するために継承することを提案しています。

24.4.2 基本イテレータ
テンプレートは 、iterator新しいイテレータに必要な型の定義を容易にする基本クラスとして使用できます。

namespace std {

    template<class Category, class T, class Distance = ptrdiff_t,
             class Pointer = T*, class Reference = T&>
    struct iterator {
        typedef T value_type;

        typedef Distance difference_type;

        typedef Pointer pointer;

        typedef Reference reference;

        typedef Category iterator_category;

    };

}

または、同じ typedef のセットを既存のクラスに追加することもできます。

于 2012-05-07T16:03:38.537 に答える