This question already has answers here:
Can I list-initialize a vector of move-only type?
(8 answers)
initializer_list and move semantics
(9 answers)
Closed 4 years ago.
UPD: The linked duplicate question do indeed resolve the issue. Thank you, everyone, for your suggestions.
Suppose I have the following class:
class NonCopyableInt {
public:
NonCopyableInt(const int &source) : data{source} {
}
NonCopyableInt(const NonCopyableInt &val) = delete;
void operator=(const NonCopyableInt &other) = delete;
NonCopyableInt(NonCopyableInt &&val) {
data = val.data;
}
int data;
};
Now, I'm using it this way:
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
for (const auto &v : vec) {
os << v << " ";
}
return os;
}
ostream &operator<<(ostream &os, const NonCopyableInt &v) {
os << v.data << " ";
return os;
}
int main(){
{
cout << "partial move" << endl;
vector<NonCopyableInt> v;
v.push_back(NonCopyableInt(1));
v.push_back(NonCopyableInt(2));
v.push_back(NonCopyableInt(3));
v.push_back({3});
vector<NonCopyableInt> vref;
cout << v << endl;
cout << vref << endl;
vref.push_back(move(v[0]));
v.clear();
cout << v << endl;
cout << vref << endl;
}
return 0;
}
This works perfectly fine and as expected. I am able to move objects between vectors without copying them. However, here is my question:
Why can I do this:
v.push_back({3});
But can't do this(causes the following compilation error: error: call to deleted constructor of 'NonCopyableInt'):
vector<NonCopyableInt> v{{1},{2}}
?
My guess is that when I call vector constructor, it can't accept element by rvalue or what?
Thank you.
Related
This question already has answers here:
How come a non-const reference cannot bind to a temporary object?
(11 answers)
Error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
(2 answers)
cannot bind non-const lvalue reference of type to an rvalue of type
(1 answer)
Closed 3 months ago.
I try to overload operator << and ++ (post and pre).
This is part of my code, but I get error "e0349: no operator matches these operands".
Could you tell me where I made a mistake?
(C++, VS2022)
#include <iostream>
#include <string>
using namespace std;
class K {
int x, y;
public:
K(int a, int b) :x(a), y(b) {};
K() :x(0), y(0) {};
K operator++(int);
K& operator++();
friend ostream& operator<< (ostream & str, K & obj);
};
K K::operator++(int) {
K temp(*this);
x += 1;
y += 1;
return temp;
}
K& K::operator++() {
x += 1;
y += 1;
return *this;
}
ostream& operator<<(ostream& str, K& obj) {
str << "[" << obj.x << ", " << obj.y << "]";
return str;
}
int main(int argc, char* argv[])
{
K obj{10, 20};
cout << obj++ << endl; //here I get error
cout << obj << endl;
cout << ++obj << endl;
}
Simply the post-operator++ is written so that it returns a copy of the temporary value which can be used as rvalue but being that the signature of the insertion operator requires a reference of the value, it does not know how to retrieve the data passed as a copy. This is how you should modify the overloading function of the extract operator:
ostream& operator<<(ostream& str, K const& obj) {
str << "[" << obj.x << ", " << obj.y << "]";
return str;
}
You're simply telling the function that the passed value will have a constant reference that it won't change over time. So it is as if you are taking the reference of the copy value. I know it's very tricky as a thing but I should have cleared your minds enough
This question already has answers here:
How to properly overload the << operator for an ostream?
(6 answers)
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 2 years ago.
string var = "Hello";
cout << var << endl;
We get the result using only the object, without the help of a member variable. I want to implement a class that will work like string. For example:
class Test {
public:
int x = 3;
};
Test var2;
cout << var2 << endl;
How can I get implement the class so the cout line prints the value of x without referring to it?
The std::string class has operator << overloaded, that's why when you write:
std::string text = "hello!";
std::cout << var1 << std::endl; // calling std::string's overloaded operator <<
Prints the text held by it simply.
Thus, you need to overload the << operator for the class:
class Test {
int x = 3;
public:
friend std::ostream& operator<<(std::ostream& out, const Test& t) {
out << t.x;
return out;
}
}
// ...
Test var2;
std::cout << var2 << std::endl;
This question already has answers here:
How do I print out the contents of a vector?
(31 answers)
Closed 3 years ago.
I would like to print the vector values in the friend overloaded operator <<.
The class is here:
#ifndef FOR_FUN_TESTCLASS_HPP
#define FOR_FUN_TESTCLASS_HPP
#include <utility>
#include <vector>
#include <string>
#include <ostream>
class TestClass {
public:
TestClass(uint32_t i, std::string s, std::vector<uint32_t> v) : i_(i), s_(std::move(s)), v_(std::move(v)) {}
friend std::ostream &operator<<(std::ostream &os, const TestClass &aClass) {
os << "i_: " << aClass.i_
<< " s_: " << aClass.s_
<< " v_: " << aClass.v_; //compiler error
return os;
}
private:
uint32_t i_ {0};
std::string s_;
std::vector<uint32_t> v_ {};
};
#endif //FOR_FUN_TESTCLASS_HPP
but when I invoke the main method, it does not compile
TestClass tc { 1, "one", {1,2,3}};
std::cout << tc << std::endl;
This is because the operator << does not know how to print the vector. I would like to stay in the method operator<< and print the vector. How is this done?
Error: error: no match for operator<< (operand types are
std::basic_ostream and const std::vector)
I don't want to iterate using the for operator, I am looking for a smarted solution, ie copy the vector contents in the ostream?
This will do the job:
friend std::ostream &operator<<(std::ostream &os, const TestClass &aClass) {
os << "i_: " << aClass.i_
<< " s_: " << aClass.s_
<< " v_: ";
for(auto it : aClass.v_)
os << it<<' ';
return os;
}
Live on Godbolt.
or with copy:
std::copy(aClass.v_.begin(), aClass.v_.end(),
std::ostream_iterator<uint32_t>(std::cout, ' '));
Live on Godbolt.
This question already has answers here:
Why do stream operators return references in C++?
(3 answers)
Closed 6 years ago.
#include "stdafx.h"
#include <iostream>
using namespace std;
// move operation is not implicitly generated for a class where the user has explicitly declared a destructor
class A {
public:
friend inline void operator << (ostream &os, A& a) {
os << "done" << endl;
}
};
template <typename T>
void done(T a) {
cout << a;
}
template<typename T>
void g(T h) {
cout << h << endl;
}
int main()
{
A a;
done(a);
// g(a); // with error: "mismatch in formal parameter list" and '<<': unable to resolve function overload.
return 0;
}
As the comments, it is so weird that with 'endl', the code cannot be compiled
with error: "mismatch in formal parameter list" and '<<': unable to resolve function overload.
You should return a reference to the stream so that you can chain the function calls
friend inline std::ostream& operator << (std::ostream &os, A& a) {
os << "done" << endl;
return os;
}
Not this
friend inline void operator << (ostream &os, A& a) {
os << "done" << endl;
}
When you use
friend inline void operator << (ostream &os, A& a)
the line
cout << h << endl;
is a problem since there is no operator<< between void and endl.
I learnt how to do operator overloading of Stream Insertion Operator. But one doubt remains.
#include<iostream>
class INT
{
int i;
friend std::ostream& operator<<(std::ostream&,INT&);
public:
INT():i(100){}
};
std::ostream& operator<<(std::ostream& obj,INT & data)
{
obj<<data.i;
return obj;
}
int main()
{
INT obj;
std::cout<<obj;
}
What significance return obj; has?
Do that return have any use further?
Are We forced to do that return because of the syntax of the operator<< without any usefulness?
Remember how you can write code like this:
cout << "The data is: " << somedata << endl;
This is actually the same as:
((cout << "The data is: ") << somedata) << endl;
For this to work, the << operator has to return the stream.