Thread for member functions - c++

I was trying to make threads for the following function
void SortingCompetition::masterSort(int low, int high)
like this:
thread a(&SortingCompetition::masterSort,this, low, j-1);
thread b (&SortingCompetition::masterSort,this, j+1,high);
and get the following error.
sortingcompetition.cpp:55:16: error: no matching constructor for initialization
of 'std::__1::thread'
thread b (&SortingCompetition::masterSort,this, j+1,high);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:374:9: note:
candidate constructor template not viable: requires single argument '__f',
but 4 arguments were provided
thread::thread(_Fp __f)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:263:5: note:
candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:270:5: note:
candidate constructor not viable: requires 0 arguments, but 4 were
provided
thread() _NOEXCEPT : __t_(0) {}
I'm new to threads, so I'm not sure what to do.

You have to bind the method like:
thread a(std::bind(&SortingCompetition::masterSort, this, std::placeholders::_1, std::placeholders::_2),low,j-1);
Alternative you can use a function or static method. The reason is, that due binding the this pointer is preserved. To invoke the method of an instance wich is not static, you need the this pointer. With std::bind this is done. std::bind needs to now how many parameters the method has, thats where the placeholder come into game.

Related

overloading global function with unique_ptr and raw pointers [duplicate]

This question already has answers here:
C++ - compilation fails on calling overloaded function in std::thread
(2 answers)
Closed 2 years ago.
I've been developing a feature in c++, that is using some legacy code written C language.
I've been facing compiler error with overloaded versions of a function that either takes unique_ptr or a raw pointer of the same type.
Simplified version of my code is given below:
class A{
public:
A():mDummy(0) { }
~A()=default;
int mDummy;
};
void handleObj(std::unique_ptr<A> ap){
std::cout<<ap->mDummy<<'\n';
}
void handleObj(A* ap){
std::cout<<ap->mDummy<<'\n';
}
int main(){
std::unique_ptr<A> obj{new A()};
std::thread t1{handleObj, std::move(obj)};
A* obj2{ new A()};
std::thread t2{handleObj, obj2};
if(t1.joinable())
t1.join();
if(t2.joinable())
t2.join();
}
when compiled getting this error:
/Users/overload_uniquePtr_rawPtr/main.cpp:29:17: error: no matching constructor for initialization of 'std::thread'
std::thread t1{handleObj, std::move(obj)};
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/thread:359:9: note: candidate template ignored: couldn't infer template argument '_Fp'
thread::thread(_Fp&& __f, _Args&&... __args)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
thread(const thread&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/thread:315:5: note: candidate constructor not viable: requires single argument '__t', but 2 arguments were provided
thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = _LIBCPP_NULL_THREAD;}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
Can some body help me understand whats wrong here?
From what I understand the compiler cant deduce which of the functions you want to construct std::thread with. There's a proposal for a std::overload which I believe would help you out but right now you can do something like this:
std::thread t1([](auto&& x) { handleObj(std::forward<decltype(x)>(x)); }, std::move(obj));
The problem is caused by the template reduction failure . The thread object's construct function is a template,it will fail when the argument function is overloaded. You can solve it like this:
std::thread t1{static_cast<void (*)(std::unique_ptr<A>)>(handleObj),obj};

LLVM MDNode inheritence

I need to create a DIVariable from an existing MDNode.
According to the documentation, DIVariable inherits from MDNode. But directly attempting to create gives the error:
error: no matching constructor for initialization of 'llvm::DIVariable'
DIVariable newDIVar(*newMDNode);
^ ~~~~~~~~~~
/root/llvm-7.0.0/include/llvm/IR/DebugInfoMetadata.h:2193:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'llvm::MDNode' to 'const llvm::DIVariable' for 1st
argument
class DIVariable : public DINode {
I tried going one level further and creating a DINode from the MDNode to see if that works, which gives a similar error:
error: no matching constructor for initialization of 'llvm::DINode'
DINode newDINode(*newMDNode);
^ ~~~~~~~~~~
/root/llvm-7.0.0/include/llvm/IR/DebugInfoMetadata.h:155:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'llvm::MDNode' to 'const llvm::DINode' for 1st
argument
class DINode : public MDNode {
That error doesnt make sense to me. How does a class that inherits from another not convert to it implicitly?
Found an answer for anyone searching in the future.
In r234255 many implicit copy constructors were removed in favor of cast<>, isa<>, and dyn_cast<>.

In C++, when no constructor is declared for a class, what will happen if I construct an object with arguments?

I have the struct student and I did not declare a constructor. What will happen if I do the following?
struct student{
int assns, mt, finalExam;
float grade(){…}
}
student billy (60, 70, 80);
This answer is written according to the question heading, and not the body, as they seem to be gravely conflicting, hope the OP edits this.
You will encounter a error during compile time.
Code:
#include <iostream>
class test
{
int tt;
};
int main ()
{
test t1 (34);
}
Compiler Error:
In function 'int main()':
10:17: error: no matching function for call to 'test::test(int)' 10:17: note: candidates are:
2:7: note: test::test()
2:7: note: candidate expects 0 arguments, 1 provided
2:7: note: constexpr test::test(const test&)
2:7: note: no known conversion for argument 1 from 'int' to 'const test&'
2:7: note: constexpr test::test(test&&)
2:7: note: no known conversion for argument 1 from 'int' to 'test&&'
This happens as there is no constructor defined which takes a parameter. Without the ctor there is no meaning of class, as you can never initialize its data member, and how can you expect something to be constructed if the construction company itself is absent.
The compiler will throw error.

Adding to a Protocol Buffers repeated field

I'm working in C++ with a Protocol Buffer template including the following message:
message StringTable {
repeated bytes s = 1;
}
I'm attempting to add a new value to the existing data, like so:
pb.stringtable().s().Add(replace_key);
However, this generates an error on compilation (using clang on OS X):
test.cpp:51:4: error: member function 'Add' not viable: 'this' argument
has type 'const ::google::protobuf::RepeatedPtrField< ::std::string>',
but function is not marked const
pb.stringtable().s().Add(replace_key);
^~~~~~~~~~~~~~~~~~~~
Any clues? I'm very much a C++ newbie so may be making a dumb error.
Edit:
Using the accessors produces a similar error:
pb.stringtable().add_s(replace_key);
results in:
test.cpp:51:21: error: no matching member function for call to 'add_s'
pb.stringtable().add_s(replace_key);
~~~~~~~~~~~~~~~~~^~~~~
./osmformat.pb.h:3046:26: note: candidate function not viable: 'this' argument has type 'const ::StringTable', but method is not marked const
inline void StringTable::add_s(const ::std::string& value) {
^
./osmformat.pb.h:3050:26: note: candidate function not viable: 'this' argument has type 'const ::StringTable', but method is not marked const
inline void StringTable::add_s(const char* value) {
^
./osmformat.pb.h:3043:36: note: candidate function not viable: requires 0 arguments, but 1 was provided
inline ::std::string* StringTable::add_s() {
^
./osmformat.pb.h:3054:26: note: candidate function not viable: requires 2 arguments, but 1 was provided
inline void StringTable::add_s(const void* value, size_t size) {
Problem solved.
The existing StringTable isn't mutable by default. However, using the mutable_ accessors makes it so:
pb.mutable_stringtable().add_s(replace_key);

How do I create an object variable from a function call?

We are using an custom image class written by our professor. I can load images like this
SimpleGrayImage in("images/uni01.pgm");
Now I have a function that looks like this
SimpleGrayImage apply_mask(SimpleGrayImage &img,SimpleFloatImage &mask){
and I can also uses methods on it like this apply_mask(...).show();
But I am not allowed to do this SimpleGrayImage img = apply_mask(...);
Did I miss something or could it be that our professor forgot to add another constructor?
test.cpp:133:43: error: no matching function for call to ‘SimpleGrayImage::SimpleGrayImage(SimpleGrayImage)’
SimpleGrayImage img = apply_mask(in,mask);
^
test:133:43: note: candidates are:
In file included from SimpleFloatImage.h:13:0,
from aufgabe11_12_13.cpp:13:
SimpleGrayImage.h:110:2: note: SimpleGrayImage::SimpleGrayImage(const string&)
SimpleGrayImage(const std::string& filename);
^
SimpleGrayImage.h:110:2: note: no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘const string& {aka const std::basic_string<char>&}’
SimpleGrayImage.h:91:2: note: SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)
SimpleGrayImage(SimpleGrayImage &img);
^
SimpleGrayImage.h:91:2: note: no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘SimpleGrayImage&’
SimpleGrayImage.h:86:2: note: SimpleGrayImage::SimpleGrayImage(int, int)
SimpleGrayImage(int wid, int hig);
^
SimpleGrayImage.h:86:2: note: candidate expects 2 arguments, 1 provided
SimpleGrayImage.h:80:2: note: SimpleGrayImage::SimpleGrayImage()
SimpleGrayImage();
^
SimpleGrayImage.h:80:2: note: candidate expects 0 arguments, 1 provided
From the errors i can see that the copy constructor is not defined correctly:
SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)
This will not be called since the value you return from function apply_mask is not local variable but an rvalue.
For the constructor to take rvalues you need to change the signature of the copy constructor to
SimpleGrayImage::SimpleGrayImage(const SimpleGrayImage&)//note the new const
Edit: For more information on rvalues you can check this link. Rvalues can be converted to const SimpleGrayImag& a = apply_mask() because the const ensures that you can't make changes to a so the compiler can safely give you the address of that local memory. The definition without const can only be used on lvalues like such:
SimpleGrayImag a;//this is an lvalue;
SimpleGrayImag b = a;
The best approach is to use const on all the arguments that you don't want them to be output arguments. Also you can make functions with both versions const and non const and most of the time the compiler will understands you, however it should be avoided because the code is harder to read and understand.