Thread (Attempt to use a deleted function - c++

I'm following an online tutorial on threading and got the error message "Semantic Issue: Attempt to use a deleted function". Any idea what's wrong?
#include <iostream>
#include <thread>
#include <string>
using namespace std;
class Fctor {
public:
void operator() (string & msg) {
cout << "t1 says: " << msg << endl;
msg = "msg updated";
}
};
int main(int argc, const char * argv[]) {
string s = "testing string " ;
thread t1( (Fctor()), s);
t1.join();
return 0;
}

Well, the code works with VS2015, MS-Compiler, with these change to the code:
This
void operator() (string & msg) {
cout << "t1 says: " << msg << endl;
msg = "msg updated";
}
to
void operator() (std::string& msg) {
std::cout << "t1 says: " << msg.c_str() << std::endl;
msg = "msg updated";
}
and this
string s = "testing string " ;
thread t1( (Fctor()), s);
to
std::string s = "testing string ";
Fctor f;
std::thread t1(f, s);
The two main things I changed was msg.c_str(), because the stream doesn't take string, but const char*.
Second, I turned the RValue Fctor() into the LValue Fctor f and gave f as the parameter, the thread apparently doesn't take RValues.

Related

In C++ is there a way to call a function with a std::stringstream& argument without the caller using a named variable?

In C++, is it possible to call a function whose argument is std::stringstream& without the caller declaring an explicit named variable of type std::stringstream?
I.e. I would like to accomplish something along the lines of this:
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
void func(const std::stringstream& ss) {
std::cout << ss.str() << std::endl;
}
int main() {
func("Hello World " << errno << "(" << strerror(errno) << ")");
return 0;
}
The above code generates this compile error:
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
./main.c: In function ‘int main()’:
./main.c:11:23: error: invalid operands of types ‘const char [13]’ and ‘int’ to binary ‘operator<<’
11 | func("Hello World " << errno << "(" << strerror(errno) << ")");
| ~~~~~~~~~~~~~~ ^~
| |
| const char [13]
(I'm not sure if I properly understand the problem -- I think it is because the const char* "Hello World" is not implicitly cast to anything for which the << operator is applicable -- is that correct?)
I tried this next:
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
void func(const std::stringstream& ss) {
std::cout << ss.str() << std::endl;
}
int main() {
func(std::stringstream("Hello World ") << errno << "(" << strerror(errno) << ")");
return 0;
}
...which had an interesting result: on my PC, with g++ I got the following compile error:
$ g++ -g ./main.c && ./a.out
./main.c: In function ‘int main()’:
./main.c:19:77: error: invalid initialization of reference of type ‘const stringstream&’ {aka ‘const std::__cxx11::basic_stringstream<char>&’} from expression of type ‘std::basic_ostream<char>’
19 | func(std::stringstream("Hello World ") << errno << "(" << strerror(errno) << ")");
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
./main.c:6:36: note: in passing argument 1 of ‘void func(const stringstream&)’
6 | void func(const std::stringstream& ss) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~
If I understand the compile error correctly, the value being passed to func() is of type std::basic_ostream<char> which cannot be implicitly cast to std::stringstream. Is this because the return-value of operator<< is type std::basic_ostream? (https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt)
The interesting part, though, is that at randomly-chosen online C++ compiler https://www.programiz.com/cpp-programming/online-compiler/, the same code compiles, however what gets printed to stdout is:
0(Success)d
...which seems to show the string "Hello World" being overwritten by the the value of errno << "(" << strerror(errno) << ")"
I presume this difference of behavior is due to different compilers, and I would like to understand if/why this is the case -- but this is tangential to the specific question asked here, and I may ask it as a separate, specific question.
tl;dr: in the following code, function main() invokes function func() by using an explicit local, named variable:
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
void func(const std::stringstream& ss) {
std::cout << ss.str() << std::endl;
}
int main() {
std::stringstream ss;
ss << "Hello World " << errno << "(" << strerror(errno) << ")";
func(ss);
return 0;
}
$ g++ -g ./main.c && ./a.out
Hello World 0(Success)
...is there a way to invoke function func() without the the caller using an explicit, named variable?
Update: I tried the following based on an answer-as-comment:
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
void func(const std::stringstream& ss) {
std::cout << ss.str() << std::endl;
}
int main() {
func(std::stringstream{} << "Hello World " << errno << "(" << strerror(errno) << ")");
return 0;
}
...which resulted in this compile-error:
$ g++ -g ./main.c && ./a.out
./main.c: In function ‘int main()’:
./main.c:46:81: error: invalid initialization of reference of type ‘const stringstream&’ {aka ‘const std::__cxx11::basic_stringstream<char>&’} from expression of type ‘std::basic_ostream<char>’
46 | func(std::stringstream{} << "Hello World " << errno << "(" << strerror(errno) << ")");
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
./main.c:6:36: note: in passing argument 1 of ‘void func(const stringstream&)’
6 | void func(const std::stringstream& ss) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~
...which looks the same as when I tried func(std::stringstream("Hello World ") << errno << "(" << strerror(errno) << ")");
Update: I tried the following based on an answer-as-comment:
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
void func(const std::stringstream& ss) {
std::cout << ss.str() << std::endl;
}
int main() {
func((std::stringstream{} << "Hello World " << errno << "(" << strerror(errno) << ")").str());
return 0;
}
...which resulted in this compile error:
$ g++ -g ./main.c && ./a.out
./main.c: In function ‘int main()’:
./main.c:11:90: error: ‘class std::basic_ostream<char>’ has no member named ‘str’
11 | func((std::stringstream{} << "Hello World " << errno << "(" << strerror(errno) << ")").str());
|
One possibility would be to use a string instead of a stringstream:
func(std::string("Hello World ") + std::to_string(errno) + "(" + strerror(errno) + ")");
...or possibly, if you don't mind one extra line elsewhere:
using namespace std::literals;
// ...
func("Hello World "s + std::to_string(errno) + "(" + strerror(errno) + ")");
Either way, you would need to rewrite func to receive an std::string (or a std::string const &) instead of an std::stringstream (but given that all func is doing with it is calling str() to get a string, that doesn't seem like it should be a problem).
Another possibility would be to rewrite func to to be a variadic template:
template <typename... Args>
void func(Args&&... args) {
((std::cout << std::forward<Args>(args)), ...);
// or if you want writing to the stream to be atomic, write them
// to a stringstream then write that to std::cout:
// std::stringstream foo;
// ((foo << std::forward<Args>(args)), ...);
// std::cout << foo.str();
}
int main() {
func("Hello World ", errno, " (", strerror(errno), ")");
}
...which produces the expected result:
Hello World 0 (Success)
May be not what you are looking for, but sometimes it used this way:
#include <cerrno>
#include <cstring>
#include <iostream>
#include <sstream>
namespace { // Just to hide from other modules
class mystream : public std::stringstream
{
public:
~mystream() {
std::cout << str() << std::endl;
}
};
}
mystream func() {
return {};
}
int main() {
func() << "Hello World " << errno << "(" << strerror(errno) << ")";
return 0;
}
As a sidnote, C++ has its own mechanisms to handle errno, you can try to use it this way:
#include <system_error>
#include <iostream>
#include <sstream>
class mystream : public std::stringstream
{
public:
~mystream() {
std::cout << str() << std::endl;
}
};
mystream func() {
return {};
}
int main() {
// Capture error for possible transmission and later processing
std::error_code err{errno, std::system_category()};
// You can compare it to platform-independent enum
if (err == std::errc::invalid_argument)
return 1;
// You can print it
func() << "Hello World " << err.value() << "(" << err.message() << ")";
return 0;
}
You can define a user defined literal.
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
std::stringstream operator ""_ss(const char* str, size_t size) {
std::stringstream ss;
ss.write(str, size);
return ss;
}
void func(const std::stringstream& ss) {
std::cout << ss.str() << std::endl;
}
int main() {
func("Hello World "_ss << errno << " (" << std::strerror(errno) << ")");
}
// Output:
// Hello World 0 (Success)
https://godbolt.org/z/bn7sq97Wq
As for the compiler error in your second attempt
func((std::stringstream{} << "Hello World " << errno << "(" << strerror(errno) << ")").c_str());
// ^^^^^^^
// Absolutely unnecessary:
func(std::stringstream{} << "Hello World " << errno << "(" << strerror(errno) << ")");
It does not work until GCC 11.2. std::basic_stringstream inherits std::basic_ostream and the returned type of its std::basic_ostream<CharT,Traits>::operator<< is basic_ostream& that is not suitable for const std::stringstream&. The work around is the modified func():
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
std::stringstream operator ""_ss(const char* str, size_t size) {
std::stringstream ss;
ss.write(str, size);
return ss;
}
void func(const std::ostream& ss) {
std::cout << ss.rdbuf() << std::endl;
}
int main() {
func("Hello World "_ss << errno << " (" << std::strerror(errno) << ")");
}
https://godbolt.org/z/szqvrcbW8

Does the stream operator exist for class member functions?

I included the logger from boost. I'm pretty pleased how it works. Just for simplicity and the reason I don't want to use makros to often in my code, I wrap it in a class.
I now wonder if I could use the streaming operator << to write on a member function.
code
class LogWrapper{
...
//debug function
//info function
...
}
void main() {
LogWrapper log;
log.debug() << "some debug msg"; // does this exist?
log.info() << "some info msg";
}
output
[some_timestamp][debug] some debug msg
[some_timestamp][info] some info msg
Is this possible in a good practice, or is it entirely bad style?
It can be done easily like this:
#include <iostream>
class A {
public:
std::ostream &debug() const {
std::cerr << "[timestamp]" << "[DEBUG]";
return std::cerr;
}
};
int main()
{
A a;
a.debug() << "Test";
}
But the important question here is: Should we implement it in this way? In my opinion, NO!
Because you are thinking that the User of the class will print the logs like this:
int main()
{
A a;
a.debug() << "Test" << std::endl;
a.debug() << "Test2" << std::endl;
}
Output:
[timestamp][DEBUG]Test
[timestamp][DEBUG]Test2
But what if User chooses this way:
int main()
{
A a;
auto &out = a.debug();
out << "Test" << std::endl;
out << "Test2" << std::endl;
}
Output:
[timestamp][DEBUG]Test
Test2
I would highly recommend not to return stream object. You should use member functions for this purpose.
#include <iostream>
class A {
public:
static void debug(const std::string &log) {
std::cerr << "[timestamp]" << "[DEBUG]" << log << std::endl;
}
};
int main()
{
A::debug("Test 1");
A::debug("Test 2");
}
Output:
[timestamp][DEBUG]Test 1
[timestamp][DEBUG]Test 2

Return a value from lambda function inside a function c++

I am working with RabbiMQ (RPC) and I want to return a value from a lambda function. I am calling this function from main.cpp but the return value is not as expected (the value inside the lambda function is as expected). What is the right syntax for this?
My code:
bool RabbitMqHandler::sendResultToUserCountService(analyze_result result, Camera *cam)
{
std:: string queueName = "userCountServiceReceiveRPC" + std::to_string(cam->getUserGroupId());
const std::string correlation("2");
SimplePocoHandler handler("localhost", 5672);
AMQP::Connection connection(&handler,
AMQP::Login("localhost","123456!"),"/");
bool isExist;
AMQP::Channel channel(&connection);
AMQP::QueueCallback callback = [&](const std::string &name,
int msgcount,
int consumercount)
{
ProtobufLPR::CarResult carResult;
carResult.set_licensenumber(result.LicenseNumber);
carResult.set_analyzetime(result.Date);
std::string buf;
carResult.SerializeToString(&buf);
AMQP::Envelope env(buf);
env.setCorrelationID(correlation);
env.setReplyTo(name);
channel.publish("", queueName, env);
std::cout << "Requesting " << result.LicenseNumber << std::endl;
};
channel.declareQueue(AMQP::exclusive).onSuccess(callback);
auto receiveCallback = [&](const AMQP::Message &message,
uint64_t deliveryTag,
bool redelivered) ->bool
{
if(message.correlationID() != correlation)
return 1;
std::cout<<"Got " << message.message() <<std::endl;
handler.quit();
istringstream(message.message()) >> isExist;
return isExist;
};
channel.consume("", AMQP::noack).onReceived(receiveCallback);
handler.loop();
}
Here is an example of returning a value from lambda function.
Live demo.
#include <iostream>
#include <iomanip>
int main() {
auto greater_than_30 = [](int value) {
return value > 30;
};
std::cout << "is 45 greater than 30? " << std::boolalpha
<< greater_than_30(45) << "\n";
return 0;
}

Putting a value to ostream

I have this code below which parses a for statement, but I am not sure how to put any value into the ostream when calling the method write(...). What can I do? (e.g write("for (........."))
#include <ostream>
#include <iostream>
using namespace std;
//I cut out the declaration bit here
typedef const string type;
private:
type *initializer;
type *condition;
type *increment;
type *body;
public:
void write(ostream& stream) const {
stream
<< "for ("
<< *initializer << "; "
<< *condition << "; "
<< *increment << ")\n{\n"
<< *body
<< "}";
}
I guess you try to learn using ostream as an input in a function. But it seems that you mixing things that how to use classs and methods.
Maybe this is no avail but i can give you a little snippet to give you some opinion.
#include <iostream>
#include <string>
using namespace std;
typedef const string type;
type *init;
type *cond;
type *incr;
type *body;
void write(ostream& stream) {
stream
<< "for ("
<< *init << "; "
<< *cond << "; "
<< *incr << ")\n{\n"
<< *body
<< "\n}";
}
int main(int argc, char* argv[])
{
const string ini = "int i = 0";
const string con = "i < 10";
const string inc = "i++";
const string bod = "cout << i << endl;";
init = &ini;
cond = &con;
incr = &inc;
body = &bod;
write(cout);
return 0;
}
Try this code, examine and read more for more details.

Passing variable (array type) from function to "main" scope Type: std::tr1::match_results<std::string::const_iterator>

I would like to pass the variable from a function to the main scope which I'm calling, I'm trying to do like I use to do in C but it returns nothing.
I want to be able to output and deal with it after the return of the function
#include "StdAfx.h"
#include <regex>
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
std::tr1::match_results<std::string::const_iterator> match(std::string& regex, const std::string& ip,std::tr1::match_results<std::string::const_iterator> res)
{
const std::tr1::regex pattern(regex.c_str());
bool valid = std::tr1::regex_match(ip, res, pattern);
std::cout << ip << " \t: " << (valid ? "valid" : "invalid") << std::endl;
cout << "FIRST RES FOUND: " << res[1] << endl;
return res;
}
int main()
{
string regex = "(\\d{1,3}):(\\d{1,3}):(\\d{1,3}):(\\d{1,3})";
string ip = "49:22:33:444";
std::tr1::match_results<std::string::const_iterator> res;
match(regex,ip.c_str(), res);
cout << "Result >" << res[1] << "< " << endl;
_getch(); return 0;
}
When I compile and run, The output is: "FIRST RES FOUND: 49
Result ><"
It's probably a really simple solution but what do I have to do to set it for my main can read it correctly as in: "Result >49<"
Thanks in advance. :)
Option 1: Use references:
void match(string& regex, const string& ip, tr1::match_results<string::const_iterator> & res)
{
const tr1::regex pattern(regex.c_str());
bool valid = tr1::regex_match(ip, res, pattern);
cout << ip << " \t: " << (valid ? "valid" : "invalid") << endl;
cout << "FIRST RES FOUND: " << res[1] << endl;
}
Option 2: Return the result by value and store it:
tr1::match_results<string::const_iterator> match(string& regex, const string& ip)
{
tr1::match_results<string::const_iterator> res;
// ...
return res;
}
int main()
{
// ...
tr1::match_results<string::const_iterator> res = match(regex, ip);
}
On a separate note, there should be absolutely no need for all the c_str() calls, as <regex> has a perfectly functional std::string interface. Check the documentation for details, you just have to get a couple of typenames right.
Edit: Here are some basic examples on using std::string. There are equivalent constructions for std::wstring, char* and wchar_t*, but std::strings should be the most useful one.
Since <regex> support is still patchy, you should consider the TR1 and Boost alternatives, too; I provide all three and you can pick one:
namespace ns = std; // for <regex>
namespace ns = std::tr1; // for <tr1/regex>
namespace ns = boost; // for <boost/regex.hpp>
ns::regex r("");
ns::smatch rxres; // 's' for 'string'
std::string data = argv[1]; // the data to be matched
// Fun #1: Search once
if (!ns::regex_search(data, rxres, r))
{
std::cout << "No match." << std::endl;
return 0;
}
// Fun #2: Iterate over all matches
ns::sregex_iterator rt(data.begin(), data.end(), r), rend;
for ( ; rt != rend; ++rt)
{
// *rt is the entire match object
for (auto it = rt->begin(), end = rt->end(); it != end; ++it)
{
// *it is the current capture group; the first one is the entire match
std::cout << " Match[" << std::distance(rt->begin(), it) << "]: " << *it << ", length " << it->length() << std::endl;
}
}
Don't forget to handle exceptions of type ns::regex_error.
Pass in res by reference instead of by value. In other words, declare the parameter res as a reference instead of a value, i.e., type &res, not type res.