2012-05-07 21 views
2

私は奇妙な問題についていくつかの助けをしたいと思います。コードは 、行列に関するオンラインからもらったために、私はコンパイルと++グラム上で動作するが、VCからVC++ 2008でビルドエラーを構築するために失敗することができ++すべてのヘルプは本当に感謝されマトリックスインプリメンテーションでinner_product()を呼び出す場合の相違点

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

こんにちはBoさん、ありがとうございました。 「あなたの既存のクラスに同じtypedefを追加する」という情報を私に教えてください。私はCslice_iterに追加してSlice_iterを追加しようとするが、同じエラーで追加するクラスは不明です。 –

+0

typedefは 'iterator_traits'によってイテレータの型を決定するために使われます。イテレータがランダムアクセスをサポートしている場合は、それを示す 'typedef random_access_iterator_tag iterator_category'が含まれていなければなりません。エラーには 'Cslice_iter 'と記載されているので、その候補が第一候補でなければなりません。 –

関連する問題