description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Compiler Error C2678 |
Compiler Error C2678 |
11/04/2016 |
C2678 |
C2678 |
1f0a4e26-b429-44f5-9f94-cb66441220c8 |
Compiler Error C2678
binary ‘operator’ : no operator defined which takes a left-hand operand of type ‘type’ (or there is no acceptable conversion)
To use the operator, you must overload it for the specified type or define a conversion to a type for which the operator is defined.
C2678 can occur when the left-hand operand is const-qualified but the operator is defined to take a non-const argument.
Examples
The following sample generates C2678 and shows how to fix it:
// C2678a.cpp // Compile by using: cl /EHsc /W4 C2678a.cpp struct Combo { int number; char letter; }; inline Combo& operator+=(Combo& lhs, int rhs) { lhs.number += rhs; return lhs; } int main() { Combo const combo1{ 42, 'X' }; Combo combo2{ 13, 'Z' }; combo1 += 6; // C2678 combo2 += 9; // OK - operator+= matches non-const Combo }
C2678 can also occur if you do not pin a native member before calling a member function on it.
The following sample generates C2678 and shows how to fix it.
// C2678.cpp // compile with: /clr /c struct S { int _a; }; ref class C { public: void M( S param ) { test = param; // C2678 // OK pin_ptr<S> ptest = &test; *ptest = param; } S test; };
I am really confused on why I am getting following compilation error.
Microsoft Visual Studio Compiler.
error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::string' (or there is no acceptable conversion)
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <iterator>
class MyException {
public:
MyException( std::string message,
int line = 0) : m_message(message),
m_line(line) {}
const char* what() const throw(){
if ( m_line != 0 ) {
std::ostringstream custom_message;
custom_message << "Parsing Error occured at ";
custom_message << m_line << " Line : ";
custom_message << m_message;
m_message = custom_message.str();
}
return m_message.c_str();
}
private:
std::string m_message;
int m_line;
};
int main(int argc, char **argv) {
try {
// do something
}catch(MyException &e){
std::cout << e.what();
}
}
Error is coming at line
m_message = custom_message.str();
asked Aug 11, 2011 at 6:20
1
You declare the method as const
const char* what() const throw(){
but then you try to change the object
m_message = custom_message.str();
so you get an error.
What you should do instead is construct the custom message in the constructor.
class MyException {
public:
MyException(const std::string& message, int line = 0) :
m_message(message), m_line(line) {
if ( m_line != 0 ) {
std::ostringstream custom_message;
custom_message << "Parsing Error occured at ";
custom_message << m_line << " Line : ";
custom_message << m_message;
m_message = custom_message.str();
}
}
const char* what() const throw(){
return m_message.c_str();
}
private:
std::string m_message;
int m_line;
};
Also I changed your code to pass the std::string by reference, which is usual practice.
answered Aug 11, 2011 at 6:24
johnjohn
84k4 gold badges56 silver badges80 bronze badges
You are trying to assign to MyException::m_message
inside a const-qualified method MyException::what()
. Inside such what()
the entire *this
object is considered to be const
, which means that m_message
member is also const
. You can’t assign anything to a const-qualified std::string
object, since std::string
‘s assignment operator requires a modifiable (i.e. a non-const one) object on the left-hand side. You are supplying a const
one.
If you really want to be able to modify the m_message
inside what()
, you should declare it as mutable
member of the class (in this case it appears to be a good idea). Or use some other approach.
As @john noted, in your specific case it makes more sense to actually build m_message
in constructor instead of postponing it till what()
. I don’t really understand why you’d even want to rebuild your m_message
every time you call what()
. Unless your m_line
is expected to change somehow from one call to what()
to another, there’s really no need to do it every time.
answered Aug 11, 2011 at 6:24
In addition to the other answers;
You’re not including the <string>
header, which may be the cause of a problem later.
Something that used to get me a lot is that some std::
headers include others, which allows you to use a class, but maybe only with limited functionality because the std::
headers that they include are the bare minimum that is needed for that file to run. This is quite an annoyance because sometimes you declare a std::
class such as string
and you haven’t included the header, the definition will be fine but everything else may or may not work — leading you to a lot of debugging because the definition worked fine.
answered Aug 11, 2011 at 6:28
Seb HolzapfelSeb Holzapfel
3,7831 gold badge19 silver badges22 bronze badges
See the declaration of the what()
function, it is marked const
(the second const
on the line). That means that it cannot alter any member variables, in your case the m_message
string. That is why you get the error.
Now, how do you fix it?
Your code is wrong, your what()
function will prepend the "Parsing Error occured at "
etc. text each time you invoke the what()
function. So, instead of doing that having to modify the m_message
member, I suggest that you format the entire message in the ctor of the class:
MyException(std::string message, int line = 0)
{
if (line != 0)
{
std::ostringstream custom_message;
custom_message << "Parsing Error occured at ";
custom_message << line << " Line : ";
custom_message << message;
m_message = custom_message.str();
}
else
m_message = message;
}
answered Aug 11, 2011 at 6:36
wilxwilx
17.6k6 gold badges59 silver badges113 bronze badges
При компиляции Visual Studio выдает ошибку:
error C2678: бинарный «<«: не найден оператор, принимающий левый операнд типа «const _Ty» (или приемлемое преобразование отсутствует).
Что это значит и как ее исправить?
P.S. Если данные пояснения помогут, то вот они:
Структура Shape — прямоугольник, первые две координаты у которого (x0, y0) — левая нижняя его вершина, вторые две
(x1, y1) — правая верхняя. Вершины прямоугольника лежат в узлах целочисленной решетки.
Структура Point — точка хранит координаты точки x0, y0.
Функция PointInShape проверяет, лежит ли точка в прямоугольнике.
Функция PointInArea проверяет, лежит ли точка в каком-нибудь из прямоугольников, а также посещали ли мы ее ранее.
Вектор shapes — набор прямоугольников
Словарь used хранит информацию, посещена ли вершина point.
Словарь dist хранит расстояния до вершин от стартовой.
Во входном файле задано количество прямоугольников n и в следующих n строках заданы прямоугольники в виде
координат левой нижней и правой верхней вершин.
В последних двух строках заданы координаты стартовой и конечной вершин.
Разрешено посещать только те вершины, которые находятся хотя бы в одном из многоугольников.
Ходить можно только конем, как в шахматах (на две клетки вверх/вниз и на одну в перпендикулярном направлении).
Необходимо вывести в выходной файл расстояние length между вершинами или -1, если между ними нет пути.
Пример входных данных:
3
0 0 2 2
1 2 4 2
4 1 6 3
0 0
1 1
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <cstdlib>
#include <vector>
#include <map>
#include <fstream>
#include <queue>
using namespace std;
struct Shape {
long x0, y0, x1, y1;
explicit Shape(const long X0, const long Y0, const long X1, const long Y1) {
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
};
struct Point {
long x0, y0;
explicit Point(const long X0,const long Y0) {
x0 = X0;
y0 = Y0;
}
};
bool PointInShape(const Shape& shape,const Point& point) {
if (point.x0 >= shape.x0 && point.x0 <= shape.x1 &&
point.y0 >= shape.y0 && point.y0 <= shape.y1) return true;
return false;
}
bool PointInArea(const vector <Shape>& sh, const map <Point, bool>& u,const Point& point) {
bool InUsed = u.count(point);
for (const Shape& s : sh) {
if (PointInShape(s, point) && !InUsed) return true;
}
return false;
}
int main() {
ifstream file_in("infile.txt");
ofstream file_out("outfile.txt");
long n;
file_in >> n;
long x1, y1, x2, y2;
vector <Shape> shapes;
map <Point, bool> used;
map <Point, long> dist;
for (int i = 0; i < n; ++i) {
file_in >> x1 >> y1 >> x2 >> y2;
shapes.push_back(Shape( x1, y1, x2, y2 ));
}
file_in >> x1 >> y1 >> x2 >> y2;
const Point start(x1, y1);
const Point end(x2, y2);
queue <Point> points;
points.push(start);
dist[start] = 0;
long length = -1;
while (!points.empty()) {
Point point = points.front();
points.pop();
for (const Point& p : {Point(point.x0+2, point.y0+1),
Point(point.x0+2, point.y0-1),
Point(point.x0+1, point.y0+2),
Point(point.x0-1, point.y0-2)}) {
if (p.x0 == end.x0 && p.y0 == end.y0) {
length = dist[point] + 1;
file_out << length;
return 0;
}
else {
if (PointInArea(shapes, used, p)) {
points.push(p);
dist[p] = dist[point] + 1;
}
}
}
}
file_out << length;
return 0;
}
The full error is: error C2678: binary ‘<‘ : no operator found which takes a left-hand operand of type ‘const sf::Vector2f’ (or there is no acceptable conversion)
What upsets me is that the error gives no location, so this could literally be anywhere in my program. Here is the function that I think does it, but I have plenty more to post if this isn’t it.
|
|
GetBoxes() and GetRect() return vectors of my Box class objects and sf::RectangleShape objects. What does this error even mean, and how do I get around it?
No way. Even the worst template errors give a line number. Post the contents of the output window.
The error is not in that code. The only < operator is in your for statement, and it is not using sf::Vector2f.
helios is right. The error message always has the line number in it (if it’s a compiler error). You just must not be seeing it.
Sorry, I meant no line number in my own code.
error C2678: binary ‘<‘ : no operator found which takes a left-hand operand of type ‘const sf::Vector2f’ (or there is no acceptable conversion) c:program files (x86)microsoft visual studio 11.0vcincludexstddef 180 1 TicTacToe
Looking in the xstddef file, I have no way of determining what actually went wrong
@Disch: ok, so how about this code? I am also working with a std map that holds an sf::Vector2f
|
|
That’s in Boad.cpp. Here’s board.h
|
|
Last edited on
Template errors output a sort of stack of errors and you have to figure out where your code is. That’s why I asked you to post the contents of the window. Post everything.
This:
std::map<sf::Vector2f, std::vector<Box>> boxMap;
std::map uses the < operator to order its keys. There is no < operator defined for sf::Vector2f.
You have a few options… the least drastic of which would be to provide your own compare functor for the map:
|
|
Last edited on
@helios: ok, here are all the warnings that come up with the one error:
Warning 1 warning C4018: ‘<‘ : signed/unsigned mismatch c:usersjordandocumentsvisual studio 2012 projectstictactoetictactoeboard.cpp 23 1 TicTacToe
Warning 2 warning C4244: ‘argument’ : conversion from ‘int’ to ‘float’, possible loss of data c:usersjordandocumentsvisual studio 2012projectstictactoetictactoeboard.cpp 25 1 TicTacToe
Warning 3 warning C4018: ‘<‘ : signed/unsigned mismatch c:usersjordandocumentsvisual studio 2012projectstictactoetictactoeboard.cpp 31 1 TicTacToe
Error 4 error C2678: binary ‘<‘ : no operator found which takes a left-hand operand of type ‘const sf::Vector2f’ (or there is no acceptable conversion) c:program files (x86)microsoft visual studio 11.0vcincludexstddef 180 1 TicTacToe
The locations the warnings refer to (Board.cpp) can be found in the code I posted earlier.
@Disch ok thanks, but what would a third element in my map do to how it functions?
Last edited on
wh1t3crayon: you still are not posting the full error message.
When I put similar code in VS (which it looks like you are using), I get the below error:
1> main.cpp 1>c:program files (x86)microsoft visual studio 11.0vcincludexstddef(180): error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const sf::Vector2f' (or there is no acceptable conversion) 1> c:usersbenc++ libssfml-2.0includesfmlsystemtime.hpp(185): could be 'bool sf::operator <(sf::Time,sf::Time)' [found using argument-dependent lookup] 1> c:usersbenc++ libssfml-2.0includesfmlsystemstring.hpp(398): or 'bool sf::operator <(const sf::String &,const sf::String &)' [found using argument-dependent lookup] 1> c:usersbenc++ libssfml-2.0includesfmlwindowvideomode.hpp(141): or 'bool sf::operator <(const sf::VideoMode &,const sf::VideoMode &)' [found using argument-dependent lookup] 1> c:usersbenc++ libssfml-2.0includesfmlnetworkipaddress.hpp(227): or 'bool sf::operator <(const sf::IpAddress &,const sf::IpAddress &)' [found using argument-dependent lookup] 1> while trying to match the argument list '(const sf::Vector2f, const sf::Vector2f)' 1> c:program files (x86)microsoft visual studio 11.0vcincludexstddef(179) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' 1> with 1> [ 1> _Ty=sf::Vector2f 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludemap(194) : see reference to function template instantiation 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' being compiled 1> with 1> [ 1> _Ty=sf::Vector2f 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludetype_traits(743) : see reference to class template instantiation 'std::less<_Ty>' being compiled 1> with 1> [ 1> _Ty=sf::Vector2f 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludextree(1028) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled 1> with 1> [ 1> _Ty=std::less<sf::Vector2f> 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludemap(67) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled 1> with 1> [ 1> _Traits=std::_Tmap_traits<sf::Vector2f,std::vector<Box>,std::less<sf::Vector2f>,std::allocator<std::pair<const sf::Vector2f,std::vector<Box>>>,false> 1> ] 1> c:usersbendocumentsvisual studio 2012projectswxtimetestmain.cpp(28) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled 1> with 1> [ 1> _Kty=sf::Vector2f, 1> _Ty=std::vector<Box> 1> ]
The bolded/underlined section tells you where in my code the error was.
@Disch ok thanks, but what would a third element in my map do to how it functions?
There is not 3rd element. The map behaves exactly the same… it has one value per key. The only thing I changed is how it compares its keys.
std::map needs to be able to compare keys so that it can order them, and look up elements. By default, it uses the < operator to compare keys. However, as mentioned, sf::Vector2f has no operator, so we have to give it something else.
I gave it a VectorCompare struct so it will now use that struct to compare two sf::Vector2fs.
ah, you meant the build code. My apologies. So here is the full output:
|
|
1> Board.cpp 1>c:usersjordandocumentsvisual studio 2012projectstictactoetictactoeboard.cpp(23): warning C4018: '<' : signed/unsigned mismatch 1>c:usersjordandocumentsvisual studio 2012projectstictactoetictactoeboard.cpp(31): warning C4018: '<' : signed/unsigned mismatch 1>c:program files (x86)microsoft visual studio 11.0vcincludexstddef(180): error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const sf::Vector2f' (or there is no acceptable conversion) 1> c:program files (x86)sfml-2.1includesfmlsystemtime.hpp(185): could be 'bool sf::operator <(sf::Time,sf::Time)' [found using argument-dependent lookup] 1> c:program files (x86)sfml-2.1includesfmlsystemstring.hpp(398): or 'bool sf::operator <(const sf::String &,const sf::String &)' [found using argument-dependent lookup] 1> c:program files (x86)sfml-2.1includesfmlwindowvideomode.hpp(141): or 'bool sf::operator <(const sf::VideoMode &,const sf::VideoMode &)' [found using argument-dependent lookup] 1> while trying to match the argument list '(const sf::Vector2f, const sf::Vector2f)' 1> c:program files (x86)microsoft visual studio 11.0vcincludexstddef(179) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' 1> with 1> [ 1> _Ty=sf::Vector2f 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludemap(194) : see reference to function template instantiation 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' being compiled 1> with 1> [ 1> _Ty=sf::Vector2f 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludetype_traits(743) : see reference to class template instantiation 'std::less<_Ty>' being compiled 1> with 1> [ 1> _Ty=sf::Vector2f 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludextree(1028) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled 1> with 1> [ 1> _Ty=std::less<sf::Vector2f> 1> ] 1> c:program files (x86)microsoft visual studio 11.0vcincludemap(67) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled 1> with 1> [ 1> _Traits=std::_Tmap_traits<sf::Vector2f,std::vector<Box>,std::less<sf::Vector2f>,std::allocator<std::pair<const sf::Vector2f,std::vector<Box>>>,false> 1> ] 1> c:usersjordandocumentsvisual studio 2012projectstictactoetictactoeboard.h(29) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled 1> with 1> [ 1> _Kty=sf::Vector2f, 1> _Ty=std::vector<Box> 1> ] ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== |
Yeah, so…. you look at the bottom of that stack… and it tells you the line that the problem is on:
|
|
Line 29 of board.h.
Which is the line I pointed to before:
std::map<sf::Vector2f, std::vector<Box>> boxMap;
How do I use your version of the map? I have this so far, but I’m getting illegal indirection errors for it.
|
|
and then in my function
|
|
Error 4 error C2664: ‘std::_Tree_iterator<_Mytree> std::_Tree<_Traits>::insert(std::_Tree_const_iterator<_Mytree>,std::pair<_Ty1,_Ty2> &&)’ : cannot convert parameter 2 from ‘int’ to ‘std::pair<_Ty1,_Ty2> &&’ c:program files (x86)microsoft visual studio 11.0vcincludextree 1319 1 TicTacToe
Error 3 error C2100: illegal indirection c:program files (x86)microsoft visual studio 11.0vcincludextree 1319 1 TicTacToe
I’m pretty close to scrapping the map idea and finding some other way to link an area of coordinates to a class object. Are there easier ways to do this?
How do I use your version of the map?
Exactly the same as you would use your own version of the map. The only thing that really changes is the declaration line.
|
|
key.x=10 key.y=4 value=6 key.x=10 key.y=8 value=9 |
and then in my function [snip]
for(std::map<sf::Vector2f, std::vector<Box>, VectorCompare<float>>::const_iterator it = boxMap.begin(); it != boxMap.end(); ++it){
Good god, man. Use auto or at least typedef that madness:
|
|
I’m pretty close to scrapping the map idea and finding some other way to link an area of coordinates to a class object.
That might not be a bad idea. Using a Vector2f as a key seems extremely strange to me.
Can you elaborate on what you’re trying to do? Like at a high level, conceptual level?
Last edited on
Good god, man. Use auto or at least typedef that madness:
Thanks, you’re the first person to show me another way of even doing a for loop.
Can you elaborate on what you’re trying to do? Like at a high level, conceptual level?
Conceptually, I have a game board, class Board, that takes up the whole window. This board will be divided into 9 equal areas, defined by the class Box. E.g. a tic tac toe board. The Board holds a vector of 9 Box objects.
Conceptually, here is where I am stuck: I want to give each of these box objects an area of coordinates on the screen that defines them, and access them when clicked (i.e. if I click on the top left corner, then «box1» from the vector of Boxes is accessed, and I can do stuff such as draw its sprite.) I tried mapping some sfml rectangles to the box objects since sfml rectangles are graphical and can actually be placed invisibly on the screen. I just don’t know how to link the box objects to the sfml rectangle objects.
A simple grid can be accomplished with a 2D array. Although I hate using 2D arrays directly since their syntax is awkward… I usually abstract them behind another class.
Here’s something I whipped up recently that you can use:
|
|
Usage example:
|
|
I want to give each of these box objects an area of coordinates on the screen that defines them, and access them when clicked
Converting pixel coordinates to ‘grid’ coordinates is a simple division. Just divide by the number of pixels per grid entry.
Example:
|
|
Thank you for the replies. Your last post finally made me understand how templates work, but I too was hoping to avoid 2d arrays. I eventually got the code to work after thinking inside the Box (pun intended), and I just gave each box object their own sf::RectangleShape inside the box class. That way, the boxes are already linked to a set of coordinates upon creation. So for anybody else who is having a similar problem:
|
|
Then box’s constructor
|
|
Usage example:
|
|
Problem solved, thanks again.
Topic archived. No new replies allowed.
My source code is about as simple as it gets:
#include <set>
#include <string>
#include <functional>
#include <algorithm>
#include <iterator>
using namespace std;
void test() {
set<string> *S = new set<string>;
S->insert("hi");
S->insert("lo");
set<string> *T = new set<string>;
T->insert("lo");
set<string> *s = new set<string>;
set<string>::iterator l=s->begin();
set_difference(S->begin(),S->end(),T->begin(),T->end(),l);
}
So why do I get a compiler error:
c:program files (x86)microsoft visual studio 10.0vcincludealgorithm(4671): error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Ax>'
The set «s» is just a set of strings, nothing const there.
asked Apr 4, 2014 at 19:16
2
You need to use an inserter for the set_difference:
set_difference(S->begin(),S->end(),T->begin(),T->end(),std::inserter(*s, l))
Building on the comment from Neil Kirk the «exception safe» way of writing this code would be this:
set<string> S;
S.insert("hi");
S.insert("lo");
set<string> T;
T.insert("lo");
set<string> s;
set<string>::iterator l=s.begin();
set_difference(S.begin(),S.end(),T.begin(),T.end(),std::inserter(s, l));
In modern C++ there is almost never a case where you need to use new
. If you do need to dynamically allocate you should be using unique_ptr
or shared_ptr
.
answered Apr 4, 2014 at 19:28
pstrjdspstrjds
16.7k6 gold badges51 silver badges61 bronze badges
iklepov 1 / 1 / 0 Регистрация: 25.12.2013 Сообщений: 12 |
||||
1 |
||||
04.04.2016, 19:54. Показов 1809. Ответов 5 Метки нет (Все метки)
Необходимо из двух multiset вывести совпадающие строки
Ошибка C2678 бинарный «=»: не найден оператор, принимающий левый операнд типа «const std::basic_string<char,std::char_traits<char>,std::allocator<char>>» (или приемлемое преобразование отсутствует) lab 2 c:program files (x86)microsoft visual studio 14.0vcincludealgorithm 3649 Ошибка в вызове set_intersection в algorithm
0 |
7533 / 6396 / 2916 Регистрация: 14.04.2014 Сообщений: 27,856 |
|
04.04.2016, 20:49 |
2 |
vector используй.
0 |
1 / 1 / 0 Регистрация: 25.12.2013 Сообщений: 12 |
|
04.04.2016, 20:52 [ТС] |
3 |
vector используй. Мне по заданию нужно использовать multiset
0 |
7533 / 6396 / 2916 Регистрация: 14.04.2014 Сообщений: 27,856 |
|
05.04.2016, 13:57 |
4 |
Хотя бы результат должен быть в vector. Тогда не используй set_intersection(), пиши свою функцию.
0 |
avgoor 1550 / 875 / 179 Регистрация: 05.12.2015 Сообщений: 2,555 |
||||
05.04.2016, 14:27 |
5 |
|||
Сообщение было отмечено iklepov как решение Решение
Хотя бы результат должен быть в vector. Не должен.
Не забудь
2 |
1 / 1 / 0 Регистрация: 25.12.2013 Сообщений: 12 |
|
05.04.2016, 14:58 [ТС] |
6 |
Все заработало, спасибо большое
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
05.04.2016, 14:58 |
Помогаю со студенческими работами здесь set_intersection ??? не понятная ошибка. Возникает ошибка при компиляции приложения C2678 Ошибки C2678 и C2679 при компиляции кода Ошибка при использовании vector (в конце, после вывода результатов выскакивает ошибка, но сам результат коректен) Проблема такова что… Ошибка при использовании ADODB.CONNECTION при работе с dbf-файлом При использовании кода в модуле ошибка при открытии файла use Cwd; Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 6 |
Полная ошибка:
Ошибка 2 ошибка C2678: двоичный файл «==»: не найден оператор, который принимает левый операнд типа «Элемент» (или нет приемлемого преобразования) c: program files (x86) microsoft visual studio 12.0 vc включить алгоритм 1734 1 GameStore
Класс инвентаризации (файл cpp)
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <Windows.h>
#include "item.h"
class Inventory
{public:
void Inventory::viewInventory()
{
for (int i = 0; i < inventory.size(); i++)
{
Inventory::inventory[i].getItemName();
}
}
void Inventory::addItem(Item& item)
{
inventory.push_back(item);
}void Inventory::removeItem(Item& item)
{
if (std::find(inventory.begin(), inventory.end(), item) != inventory.end())
{
inventory.erase(std::remove(inventory.begin(), inventory.end(), item), inventory.end());
}
else
{
std::cout << "Item does not exist" << std::endl;
}
}
//Player Gold methods
int Inventory::getGold()
{
return playerGold;
}
void Inventory::setGold(int newGold)
{
playerGold = newGold;
}int Inventory::addGold(int newGold)
{
playerGold += newGold;
return playerGold;
}
int Inventory::removeGold(int newGold)
{
playerGold -= newGold;
return playerGold;
}
//Player Gold methodsprivate:
std::vector<Item> inventory = {};
int playerGold;
};
По сути, я пытаюсь создать систему инвентаризации, в которой хранятся объекты из класса «Предмет». Я потратил много времени на то, чтобы заставить мои циклы for и все мои методы работать, а затем, поскольку небо никогда не было более ясным, я получаю ошибку, из которой выход из моей лиги.
Класс изделия (CPP)
#include "item.h"#include <iostream>
#include <string>Item::Item(int id, std::string name, std::string description, std::string examime)
{
itemName = name;
itemID = id;
itemDescription = description;
itemExamine = examime;
}
void Item::setItemName(std::string newName)
{
itemName = newName;
}
void Item::setItemDescription(std::string newDescription)
{
itemDescription = newDescription;
}
void Item::setItemExamine(std::string newExamine)
{
itemExamine = newExamine;
}
void Item::setItemID(int newID)
{
itemID = newID;
}
std::string Item::getItemName()
{
return itemName;
}
std::string Item::getItemDescription()
{
return itemDescription;
}
std::string Item::getItemExamine()
{
return itemExamine;
}
int Item::getItemID()
{
return itemID;
}
Класс товара (заголовок)
#include <iostream>
#include <string>
class Item
{
public:
//constructor
Item::Item(int id, std::string name, std::string description, std::string examime);
//setters
void setItemName(std::string newName);
void Item::setItemDescription(std::string newDescription);
void Item::setItemExamine(std::string newExamine);
void Item::setItemID(int newID);
//getters
std::string Item::getItemName();
std::string Item::getItemDescription();
std::string Item::getItemExamine();
int Item::getItemID();
private:
std::string itemName;
int itemID;
std::string itemDescription;
std::string itemExamine;
};
Если у вас есть какой-либо совет, даже если это будет переделать всю мою систему, это было бы здорово. Занятия, очевидно, очень просты, и я собираюсь добавить гораздо больше. Это означает, что я не ищу ответ типа «Вам даже не нужен класс предметов»
Спасибо за любую помощь!
0
Решение
Кажется, что основной проблемой вашего кода является отсутствие operator==
реализация для вашего Item
класс, как говорит ошибка компилятора.
Как новичок в C ++ (не беспокойтесь: каждый из нас был новичком), вы можете спросить Зачем это op==
требуется, как вы не называете это эксплицитно в вашем коде. Ну, это правда, что вы не вызываете это явно, но код в стандартной библиотеке реализация Является ли. В частности, вы вызываете std::find
(реализовано в<algorithm>
заголовок, который цитируется в вашем сообщении об ошибке):
void Inventory::removeItem(...) { if (std::find(inventory.begin(), inventory.end(), item) != inventory.end()) { ...
std::find
нужно сравнить Item
случаи с op==
,
Итак, чтобы попытаться исправить ваш код, пожалуйста, определите operator==
для сравнения Item
с, как это:
// In the Item class header:
class Item
{
...
};
inline bool operator==(const Item& a, const Item& b)
{
// Implement your comparison logic for Items a and b.
// ...
// Return true if "a == b".
}
В качестве дополнительных примечаний, когда вы объявляете функции-члены внутри вашего класса, вам не нужно использовать Item::
префикс перед функцией-членом:
class Item { public: //constructor Item::Item(int id, std::string name, std::string description, std::string examime); //setters void setItemName(std::string newName); void Item::setItemDescription(std::string newDescription); void Item::setItemExamine(std::string newExamine); void Item::setItemID(int newID); ...
Просто делать:
class Item
{
public:
//constructor
Item(int id, std::string name, std::string description, std::string examime);
//setters
void setItemName(std::string newName);
void setItemDescription(std::string newDescription);
void setItemExamine(std::string newExamine);
void setItemID(int newID);
...
Кроме того, рассмотрите возможность создания ваших добытчиков const
, чтобы сделать ваш класс const-правильным, например:
class Item
{
public:
...
std::string getItemName() const;
std::string getItemDescription() const;
std::string getItemExamine() const;
int getItemID() const;
...
};
2
Другие решения
Других решений пока нет …