Aleks G
Aleks G

Reputation: 57326

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?

Upvotes: 2

Views: 2111

Answers (4)

qPCR4vir
qPCR4vir

Reputation: 3571

"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

Upvotes: 1

Grizzly
Grizzly

Reputation: 20201

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.

Upvotes: 1

aschepler
aschepler

Reputation: 72431

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.

Upvotes: 1

ipc
ipc

Reputation: 8143

idx has to be a const_iterator since validValues is a const vector<...>.

std::vector<std::string>::const_iterator idx;

Upvotes: 5

Related Questions