Need a fix for c++ script (not mine) - c++

I have the following code in a script that I am trying to build.
typedef std::vector< typename Sphere::vec_type > VV;
typedef typename Sphere::vec_type vec_type;
VV v( count , s.dimension() );
for ( int ii=0; ii<count; ++ii ) {
v[ii] = randomPointOnSurface( s );
It produces this error:
error: no matching function for call to 'std::vector<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > >::_M_fill_initialize(size_t, int&)'
/usr/include/c++/4.4/bits/stl_vector.h:1033: note: candidates are: void std::vector<_Tp, _Alloc>::_M_fill_initialize(size_t, const _Tp&) [with _Tp = std::vector<float, std::allocator<float> >, _Alloc = std::allocator<std::vector<float, std::allocator<float> > >]
A workaround is to remove s.dimension() but is there any other way that this can fixed?

You have a nested vector, so you need something like
VV v( count , vec_type(s.dimension()) );
This initializes each of the count inner vectors to have size s.dimension().

Related

Passing arguments to constructor results in an error

I have a constructor which constructs a matrix, represented by a 2D vector, rows and columns number.
Matrix(const vector<vector<T> >* vect, const size_t rows, const size_t cols) :
matrix(&vect), matrixRows(rows), matrixCols(cols){}
I want to find the transpose of a matrix in one of my functions.
Matrix& trans() const
{
vector<vector<T> > trans(matrixCols, vector<T>(matrixRows));
for(unsigned int i = 0; i < matrixRows; i++)
{
for(unsigned int j = 0; j < matrixCols; j++)
{
trans[j][i] = matrix[i][j];
}
}
return Matrix(&trans, matrixCols, matrixRows);
}
The last line results in an error, because passing a vector this way is wrong.
What is the correct way?
Full error:
Multiple markers at this line
- invalid initialization of non-const reference of type 'Matrix<Complex>&' from an rvalue of type
'Matrix<Complex>'
- required from 'Matrix<T>& Matrix<T>::trans() const [with T = int]'
- invalid initialization of non-const reference of type 'Matrix<double>&' from an rvalue of type
'Matrix<double>'
- invalid initialization of non-const reference of type 'Matrix<int>&' from an rvalue of type 'Matrix<int>'
- required from 'Matrix<T>& Matrix<T>::trans() const [with T = Complex]'
- required from 'Matrix<T>& Matrix<T>::trans() const [with T = double]'
constructor error:
Multiple markers at this line
- invalid conversion from 'const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >**' to 'std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::size_type
{aka long long unsigned int}' [-fpermissive]
- candidate expects 3 arguments, 1 provided
- no matching function for call to 'std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::vector(const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > >
>**)'
- no known conversion for argument 1 from 'std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >' to 'const std::vector<std::vector<double, std::allocator<double> >,
std::allocator<std::vector<double, std::allocator<double> > > >*'
- candidate: Matrix<T>::Matrix(const std::vector<std::vector<T> >*, size_t, size_t) [with T = double; size_t = long long unsigned int]
- no known conversion for argument 1 from 'std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >' to 'const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int>
> > >*'
- candidate: Matrix<T>::Matrix(const std::vector<std::vector<T> >*, size_t, size_t) [with T = int; size_t = long long unsigned int]
- no matching function for call to 'std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >::vector(const std::vector<std::vector<Complex, std::allocator<Complex> >,
std::allocator<std::vector<Complex, std::allocator<Complex> > > >**)'
- invalid conversion from 'const std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >**' to 'std::vector<std::vector<Complex, std::allocator<Complex> >,
std::allocator<std::vector<Complex, std::allocator<Complex> > > >::size_type {aka long long unsigned int}' [-fpermissive]
- no matching function for call to 'std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >::vector(const std::vector<std::vector<double, std::allocator<double> >,
std::allocator<std::vector<double, std::allocator<double> > > >**)'
- invalid conversion from 'const std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >**' to 'std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double,
std::allocator<double> > > >::size_type {aka long long unsigned int}' [-fpermissive]
- no known conversion for argument 1 from 'std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >' to 'const std::vector<std::vector<Complex, std::allocator<Complex> >,
std::allocator<std::vector<Complex, std::allocator<Complex> > > >*'
- candidate: Matrix<T>::Matrix(const std::vector<std::vector<T> >*, size_t, size_t) [with T = Complex; size_t = long long unsigned int]
First off, you probably want the Matrix constructor to take the vector by reference instead of address:
Matrix(const vector<vector<T>>& vect, const size_t rows, const size_t cols)
: matrix(vect), matrixRows(rows), matrixCols(cols)
{
}
(Note that this will cause the vector to be copied into matrix. Depending on the size of the vector, this might be fine - it really depends on the performance requirements of your program.)
Secondly, trans() should not return a reference to a Matrix. Since you are returning the value of a local, the variable will be destroyed when execution leaves the function, so the caller would have no way to make use of it.
Combined with the change to the Matrix constructor above, trans() should compile now:
Matrix trans() const
{
vector<vector<T>> trans(matrixCols, vector<T>(matrixRows));
for(unsigned int i = 0; i < matrixRows; i++)
{
for(unsigned int j = 0; j < matrixCols; j++)
{
trans[j][i] = matrix[i][j];
}
}
return Matrix(trans, matrixCols, matrixRows);
}

How could I implement a vector of stack?

I am currently trying to implement a class with a vector of stacks. The class shall work as a stack to other objects but distribute the data to different stacks of a maximum size internally. If a stack is full a new one is created and pushed to the internal vector.
My current approach generates errors:
prog.cpp: In instantiation of ‘SetOfStack<T>::SetOfStack(int) [with T = int]’:
prog.cpp:54:32: required from here
prog.cpp:13:17: error: no matching function for call to ‘std::vector<std::stack<int, std::deque<int, std::allocator<int> > >, std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::push_back(std::stack<int, std::deque<int, std::allocator<int> > >*)’
stacks.push_back( new stack<T> );
^
/usr/include/c++/4.8/bits/stl_vector.h:901:7: note: no known conversion for argument 1 from ‘std::stack<int, std::deque<int, std::allocator<int> > >*’ to ‘const value_type& {aka const std::stack<int, std::deque<int, std::allocator<int> > >&}’
/usr/include/c++/4.8/bits/stl_vector.h:919:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::stack<int, std::deque<int, std::allocator<int> > >; _Alloc = std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > >; std::vector<_Tp, _Alloc>::value_type = std::stack<int, std::deque<int, std::allocator<int> > >]
push_back(value_type&& __x)
^
/usr/include/c++/4.8/bits/stl_vector.h:919:7: note: no known conversion for argument 1 from ‘std::stack<int, std::deque<int, std::allocator<int> > >*’ to ‘std::vector<std::stack<int, std::deque<int, std::allocator<int> > >, std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::value_type&& {aka std::stack<int, std::deque<int, std::allocator<int> > >&&}’
prog.cpp: In instantiation of ‘void SetOfStack<T>::push(T) [with T = int]’:
prog.cpp:55:21: required from here
prog.cpp:22:25: error: ‘__gnu_cxx::__alloc_traits<std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::value_type’ has no member named ‘push_back’
stacks[current_stack].push_back(new stack<T>);
^
prog.cpp: In instantiation of ‘T SetOfStack<T>::pop() [with T = int]’:
prog.cpp:56:27: required from here
prog.cpp:34:25: error: ‘__gnu_cxx::__alloc_traits<std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::value_type’ has no member named ‘pop_back’
stacks[current_stack].pop_back();
^
Sample Code:
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
template <class T>
class SetOfStack {
public:
SetOfStack( int max_size ): current_stack(0), max_stack_size(max_size) {
stacks.reserve(10);
stacks.push_back( new stack<T> );
}
~SetOfStack() {
stacks.clear();
}
void push( T value ) {
stacks[current_stack].push(value);
if(stacks[current_stack].size() > max_stack_size) {
stacks[current_stack].push_back(new stack<T>);
current_stack++;
if(current_stack % 10 == 0 && current_stack > stacks.size()) {
stacks.reserve(stacks.size() + 10);
}
}
}
T pop() {
T value = stacks[current_stack].top();
stacks[current_stack].pop();
if(stacks[current_stack].size() == 0 && current_stack != 0 ) {
stacks[current_stack].pop_back();
current_stack--;
}
}
T popAt( int index ) {
T value = stacks[index].top();
stacks[index].pop();
}
private:
int current_stack;
int max_stack_size;
vector< stack<T> > stacks;
};
int main() {
// Test code
SetOfStack<int> s_o_s(3);
s_o_s.push(1);
cout << s_o_s.pop() << endl;
return 0;
}
The error you're getting is this line:
stacks.push_back( new stack<T> );
As well as this line:
stacks[current_stack].push_back(new stack<T>);
Because you have declared stacks as a non-pointer:
vector< stack<T> > stacks;
So you want to use just stack<T>() instead of new stack<T>
Additionally, std::stack does not have a function push_back, you need to use push instead.
stacks.push_back(stack<T>());
stacks[current_stack].push(value);
As well as pop and not pop_back():
stacks[current_stack].pop();
At which point, you no longer need the deletes I mentioned in my original comment, since it looks like you were not intending to call new

error: no match for 'operator[]' in... <near match>

This fail to compile in gcc 4.1.2 / RedHat 5 :
#include <string>
#include <vector>
#include <map>
class Toto {
public:
typedef std::string SegmentName;
};
class Titi {
public:
typedef Toto::SegmentName SegmentName; // import this type in our name space
typedef std::vector<SegmentName> SegmentNameList;
SegmentNameList segmentNames_;
typedef std::map<SegmentName, int> SegmentTypeContainer;
SegmentTypeContainer segmentTypes_;
int getNthSegmentType(unsigned int i) const {
int result = -1;
if(i < segmentNames_.size())
{
SegmentName name = segmentNames_[i];
result = segmentTypes_[ name ];
}
return result;
}
};
The error is :
error: no match for 'operator[]' in '(...)segmentTypes_[name]'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_map.h:340:
note: candidates are: _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)
[with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = int, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >]
Why ? The map is rather straightforward. I guess this has to do with the typedefs, but what is wrong ?
[edit] Even if I remove all the typedefs and use std::string everywhere, the problem persists... Am I misusing maps ?
std::map::operator[] is non-const and you're trying to use it from a const method.
You could achieve this using std::map::find, which returns a const_iterator:
SegmentTypeContainer::const_iterator iter = segmentTypes_.find(name);
If you're using C++11, you could also use std::map::at, which will throw an exception if the key is not found in the map:
result = segmentTypes_.at(name);
std::map::operator[] is not a const method, but you are calling it from a const method of your class. The reason for this is that it adds an element if the key is not present.
You can use C++11 at():
result = segmentTypes_.at(name); // throws exception if key not present.
or use std::map::find.
SegmentTypeContainer::const_iterator it = segmentTypes_.find(name);
if (it != segmentTypes_.end())
{
// OK, element with key name is present
result = it->second;
}

No match found for operator= (find value in vector<string>)

I'm clearly missing something here, but what?
Definition (... denotes valid code, not actual three points):
class CrmxFile {
private:
const std::vector<std::string> validValues;
int value;
public:
void setValue(std::string _value);
...
}
std::vector<std::string> CrmxFile = {...};
In the code I have this:
void Crmx::SetValue(std::string _value) {
std::vector<std::string>::iterator idx;
if((idx = std::find(validValues.begin(), validValues.end(), _value)) == validValues.end()) {
value = 0;
}
else {
value = idx - validValues.begin();
}
}
I compile this with gcc -c -std=c++0x and I get this error:
CrmxFile.cpp: In member function ‘void CrmxFile::SetValue(std::string)’:
CrmxFile.cpp:24:64: error: no match for ‘operator=’ in ‘idx = std::find [with _IIter = __gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >, _Tp = std::basic_string<char>](Id3V1::validValues.std::vector<_Tp, _Alloc>::begin [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_pointer = const std::basic_string<char>*](), Id3V1::validValues.std::vector<_Tp, _Alloc>::end [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_pointer = const std::basic_string<char>*](), (*(const std::basic_string<char>*)(& _value)))’
CrmxFile.cpp:24:64: note: candidates are:
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >& __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >::operator=(const __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&)
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >’ to ‘const __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&’
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >& __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >::operator=(__gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&&)
/usr/include/c++/4.6/bits/stl_iterator.h:702:11: note: no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >’ to ‘__gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >&&’
What am I missing? Or, alternatively, is there a better way of finding the index of a given value in a vector?
idx has to be a const_iterator since validValues is a const vector<...>.
std::vector<std::string>::const_iterator idx;
Since validValues is const, begin(), end(), and therefore this instantiation of std::find, all return std::vector<std::string>::const_iterator, not std::vector<std::string>::iterator. For const-safety, a const_iterator cannot convert to an iterator.
validValues is defined as const std::vector<std::string>. Therefore begin() and end() will return const_iterator, but you are trying to assign the result to a iterator. Converting a const_iterator to an iterator would break const correctness (since you could then go on and change the underlying object) and is therefore not allowed.
Change the definition of idx to be std::vector<std::string>::const_iterator and it should work.
"What am I missing?"
Is yours first validValues invalid?
I suggest:
void Crmx::SetValue(std::string _value) {
value = std::find(validValues.begin(), validValues.end(), _value) - validValues.begin();
}
and use the validValues.size as invalid value, not 0

stl vector::insert difference in Windows and linux?

there. I've searched my question around here but failed to find anything relevant.
This is the problem.
I have this code in the part of my program, doing kind of stupid sort by inserts.
I developed that in MSVS 2008 and it all worked fine, but when I tried to compile that with g++, it failed because of list::insert function below;
//...
pair<uint, double> NewElem(i, Prob.at(i));
bool inserted(false);
vector<pair<uint, double> >::const_iterator li = NewList.begin();
for ( vector<double>::const_iterator ji = BlocksMemory.begin() ; ji != BlocksMemory.end() ; ++ji)
{
if (NewElem.second <= *ji)
li += _SORT_BLOCK;
else
break;
}
for(;li != NewList.end() ; ++li)
{
if (NewElem.second > li->second)
{
NewList.insert(li, NewElem );
inserted = true;
break;
}
}
as one can see, li is const_iterator of NewList;
And NewElem has type pair with the same content type as NewList contents;
There you can see the response (unreadable):
main.cpp:447: error: no matching function for call to "std::vector<std::pair<unsigned int, double>, std::allocator<std::pair<unsigned int, double> > >::insert(__gnu_cxx::__normal_iterator<const std::pair<unsigned int, double>*, std::vector<std::pair<unsigned int, double>, std::allocator<std::pair<unsigned int, double> > > >&, std::pair<unsigned int, double>&)"
/usr/include/c++/4.4/bits/vector.tcc:106: note: candidates are: __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::insert(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = std::pair<unsigned int, double>, _Alloc = std::allocator<std::pair<unsigned int, double> >]
/usr/include/c++/4.4/bits/stl_vector.h:850: note: void std::vector<_Tp, _Alloc>::insert(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, size_t, const _Tp&) [with _Tp = std::pair<unsigned int, double>, _Alloc = std::allocator<std::pair<unsigned int, double> >]
What can be the reason? And what is the possible solution?
The signature of the insert member function that you are trying to use is probably:
iterator insert( iterator, const value_type& );
But the first argument that you are passing to the function is a const_iterator, that cannot be implicitly converted to a non const iterator. That code should not have worked on VS either.
The simple solution is that if you intend to modify the container you use a non-const iterator: define li as std::vector< std::pair<uint,double> >::iterator li = NewList.begin();
Also, are you sure that you want to be inserting into a std::vector? For performance reasons, a std::list would be a better choice. Also, an insert on a list doesn't invalidate existing iterators as it does for a vector.