2012-05-07 2 views
2

이상한 문제에 대한 도움을 받고 싶습니다. 코드가 , 매트릭스에 대한 온라인에서 가지고 들어 내가 컴파일 ++ g에서 실행하지만 VC에서 VC++ 2008에서 빌드 오류를 구축 실패 할 수 있습니다 ++ 어떤 도움이 정말 감사합니다매트릭스 구현의 inner_product() 호출에 대한 G ++/MSVC++ 2008 차이점

------ 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> 
*/ 

답변

0

나는 도서관이 반복자는 input_iterator 또는 잘 행동 반복자가 포함되어 있어야합니다 중첩 된 형식 정의를 찾고에 의한 random_access_iterator가 있는지 확인하려고 생각합니다. 특히 iterator_category.

표준은 적절한 정의를 얻기 위해 std::iterator에서 상속받을 것을 제안합니다. iterator 템플릿은 새 반복자에 필요한 유형의 정의를 쉽게하기 위해 기본 클래스로 사용할 수 있습니다

24.4.2 기본 반복자.

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; 

    }; 

} 

또는 당신은 당신의 기존 클래스에 형식 정의의 동일한 세트를 추가 할 수 있습니다.

+0

안녕하세요, 빠른 응답을 주셔서 감사합니다. "기존 클래스에 동일한 typedef를 추가하십시오"에 대한 정보를 제공해 주시겠습니까? 나는 Cslice_iter에 추가하고 Slice_iter를 추가하려고 시도했지만 동일한 오류로 추가 할 클래스를 모르겠습니다. –

+0

typedef는'iterator_traits'에 의해 반복자의 타입을 결정하는데 사용됩니다. 반복자가 랜덤 액세스를 지원하는 경우이를 나타내는 'typedef random_access_iterator_tag iterator_category'가 있어야합니다. 오류는'Cslice_iter '을 언급하고 있으므로, 반드시 첫 번째 후보가되어야합니다. –

관련 문제