I am trying to std::bind class functions in combination of std::unique_ptr and I have a lot of trouble getting it to work
First I have two classes
class simpleClass{
public:
simpleClass(int x){
this->simpleNumber = x;
}
int simpleNumber;
simpleClass(const simpleClass &toBeClone){
this->simpleNumber = toBeClone.simpleNumber;
}
simpleClass clone(){
simpleClass *cloned = new simpleClass(*this);
return *cloned;
}
};
class className{
public:
className(doube input){
this->someVariable = input;
}
void someFunction(std::vector<double> x, double c, std::unique_ptr<simpleClass> &inputClass, std::vector<double> &output){
std::vector<double> tempOutput;
for(int i = 0; i<x.size(); i++){
tempOutput.push_back(x[i] + c * this->someVariable + inputClass->simpleNumber);
}
output = tempOutput;
}
double someVariable;
className(const className &toBeClone){
this->someVariable = toBeClone.someVariable;
}
className clone(){
className *cloned = new className(*this);
return *cloned;
}
};
They are both some standard class, but I also implement a clone function to duplicate an initialized class. While cloning, I need to ensure that the original class and the cloned class points to different address. So I use std::unique_ptr to ensure this.
The is the main function, which also shows how I "clone"
int main(){
className testSubject(5);
std::vector<std::unique_ptr<className>> lotsOfTestSubject;
simpleClass easyClass(1);
std::vector<std::unique_ptr<simpleClass>> manyEasyClass;
for(int i = 0; i<10; i++){
std::unique_ptr<className> tempClass(new className(testSubject.clone()))
lotsOfTestSubject.push_back(std::move(tempClass));
std::unique_ptr<simpleClass> tempEasyClass(new simpleClass(easyClass.clone()))
manyEasyClass.push_back(std::move(tempEasyClass));
}
std::vector<std::vector<<double>> X; //already loaded with numbers
double C = 2;
std::vector<std::vector<<double>> OUT;
for(int i = 0; i<10; i++){
std::vector<double> tempOUT;
lotsOfTestSubject[i]->someFunction(X[i], C, manyEasyClass[i], tempOUT);
OUT.push_back(tempOUT);
//Here if I want to bind
/*
std::bind(&className::someFunction, lotsOfTestSubject[i], X[i], C, manyEasyClass[i], tempOUT);
*/
}
return 0;
}
The reason why I "clone" is because both simpleClass and className takes a lot of time for construction in my implementation, and I need a lot of them. And Since many of them will be initialized with the same parameters, I figured this is the easiest way to do so.
The code above works, but I am trying to improve the speed of the loop. The following line is where most of the computation takes place.
lotsOfTestSubject[i]->someFunction(X[i], C, manyEasyClass[i], tempOUT);
So I am attempting to use threads to delegate the work , and as far as I know, I need to std::bind first. So I tried
std::bind(&className::someFunction, lotsOfTestSubject[i], X[i], C, manyEasyClass[i], tempOUT);
But the compiler prints error like this
/usr/include/c++/5/tuple|206| recursively required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 1ul; _Head = std::vector<double>; _Tail = {double, std::unique_ptr<simpleClass, std::default_delete<simpleClass> >, std::unique_ptr<simpleClass, std::default_delete<simpleClass> >, std::vector<double>}]’|
/usr/include/c++/5/tuple|108|error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = className; _Dp = std::default_delete<className>]’|
I have no idea what this means as I just started self teaching c++. Any feedback and guidance is much appreciated.
I am using c++11 and g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Update
Thanks #rafix07, tried your solution and it works fine. but then I tried to do
auto theBinded = std::bind(&className::someFunction, &lotsOfTestSubject[i],
X[i], C, std::ref(manyEasyClass[i]), tempOUT);
std::thread testThread(theBinded);
and eventually want to testThread.join()
But the compiler says
error: pointer to member type ‘void (className::)(std::vector<double>, double, std::unique_ptr<simpleClass>&, std::vector<double>&)’ incompatible with object type ‘std::unique_ptr<className>’|
#kmdreko Thanks for you point out! I haven't notice memory leak yet, but I will fix it. Do I just use this?
std::unique_ptr<className> tempClass = new className(testSubject);
EDIT
If you want to call someFunction on instance stored in lotsOfTestSubject you need to pass pointer to className object on which this method will be called, so the line below
std::bind(&className::someFunction, lotsOfTestSubject[i]
should be replaced by:
auto theBinded = std::bind(&className::someFunction, lotsOfTestSubject[i].get(),
^^^
Second change is to use std::ref to pass original instance of unique_ptr of manyEasyClass instead of its copy. std::bind always copies or moved its arguments (see reference), but unique_ptr is non-copyable, that is why compilation failed.
So fixed line looks:
auto theBinded = std::bind(&className::someFunction, lotsOfTestSubject[i].get(),
X[i], C, std::ref(manyEasyClass[i]), std::ref(tempOUT));
tempOUT also must be passed by std::ref because you want to modify this vector by call operator() on functor created by bind.
LIVE DEMO
Related
Does anyone could explain me the reason of this coding recommendation ?
Since C++11, please initialize data members on declaration (not
necessary on constructor) :
class Limit
{
public:
Limit() = default;
private:
int32_t quantity = 0;
double price = 0.0;
};
Someone thinks (correctly) that this way the variable is always initialised. Which is a good thing if it is initialised with a meaningful value and bad if the value is not meaningful. For example a person’s year of birth is a number from say 1890 to 2021. Initialising it to 0 isn’t useful and can only prevent the compiler from warning you.
So do this if you have a value that is always a useful initialisation value. I wouldn’t do it for anything that is likely to be overwritten in a constructor or shortly after.
I found this answer from CppCoreGuidelines C-48 :
C.48: Prefer in-class initializers to member initializers in constructors for constant initializers
Reason
Makes it explicit that the same value is expected to be used in all constructors. Avoids repetition. Avoids maintenance problems. It leads to the shortest and most efficient code.
Example, bad
class X { // BAD
int i;
string s;
int j;
public:
X() :i{666}, s{"qqq"} { } // j is uninitialized
X(int ii) :i{ii} {} // s is "" and j is uninitialized
// ...
};
How would a maintainer know whether j was deliberately uninitialized (probably a bad idea anyway) and whether it was intentional to give s the default value "" in one case and qqq in another (almost certainly a bug)? The problem with j (forgetting to initialize a member) often happens when a new member is added to an existing class.
Example
class X2 {
int i {666};
string s {"qqq"};
int j {0};
public:
X2() = default; // all members are initialized to their defaults
X2(int ii) :i{ii} {} // s and j initialized to their defaults
// ...
};
Alternative: We can get part of the benefits from default arguments to constructors, and that is not uncommon in older code. However, that is less explicit, causes more arguments to be passed, and is repetitive when there is more than one constructor:
class X3 { // BAD: inexplicit, argument passing overhead
int i;
string s;
int j;
public:
X3(int ii = 666, const string& ss = "qqq", int jj = 0)
:i{ii}, s{ss}, j{jj} { } // all members are initialized to their defaults
// ...
};
Enforcement
(Simple) Every constructor should initialize every member variable (either explicitly, via a delegating ctor call or via default construction).
(Simple) Default arguments to constructors suggest an in-class initializer might be more appropriate.
There is also the guideline C-45 that explains it.
I'm trying to write a very simple array class with a function that returns a subsection of itself. It is easier to show it than to explain...
template<typename T>
class myArrayType
{
// Constructor; the buffer pointed to by 'data' must be held
// elsewhere and remain valid for the lifetime of the object
myArrayType(int size, T* data) : n(size), p(data)
{
}
// A move constructor and assign operator wouldn't make
//much sense for this type of object:
#ifndef _MSC_VER
myArrayType(myArrayType<T> &&source) = delete;
myArrayType & operator=(myArrayType<T> &&source) && = delete;
#else
#if _MSC_VER >= 2000
myArrayType(myArrayType<T> &&source) = delete;
myArrayType & operator=(myArrayType<T> &&source) && = delete;
#endif
// Earlier versions of Visual C++ do not generate default move members
#endif
// Various whole-array operations, which is the main reason for wanting to do this:
myArrayType & operator+=(const myArrayType &anotherArray) & noexcept
{
for (int i=0; i<n; ++i) p[i] += anotherArray.p[i];
return *this;
}
// etc.
// The interesting bit: create a new myArrayType object which is
// a subsection of this one and shares the same memory buffer
myArrayType operator()(int firstelement, int lastelement) noexcept
{
myArrayType newObject;
newObject.p = &p[firstelement];
newObject.n = lastelement - firstelement + 1;
return newObject;
}
private:
T* p;
int n;
}
What I'd like to do, of course, is to be able to write:
double aBigBlobOfMemory[1000]; // Keep it on the stack
myArrayType<double> myArray(1000, aBigBlobOfMemory);
myArrayType<double> mySmallerArray = myArray(250, 750);
...so that 'mySmallerArray' is a fully-formed myArrayType object which contains a pointer to a subset of myArray's memory.
In Visual Studio 2013 this seems to work (or at least, it compiles), but in gcc it fails in a way that I don't understand. The compiler error on the attempted creation of mySmallerArray is:
use of deleted function myArrayType(myArrayType<T> &&)
...with a caret pointing to the end of the line. In other words, gcc seems to think that in invoking the 'subarray operator' I'm actually trying to invoke a move constructor, but I can't for the life of me see where it would want to use one, or why.
Am I missing something really really obvious, or can anyone shed some light on this?
gcc is doing the right thing.
From operator() you are returning newObject, an instance of myArrayType. This has to be moved into the variable mySmallerArray. That's done with a move constructor, which you don't have.
You need to declare a move constructor.
It does make sense for this class to have a move constructor - it can move the pointer p from the existing instance to the new one.
When trying to get loops to auto-vectorise, I've seen code like this written:
void addFP(int N, float *in1, float *in2, float * restrict out)
{
for (i = 0 ; i < N; i++)
{
out[i] = in1[i] + in2[i];
}
}
Where the restrict keyword is needed reassure the compiler about pointer aliases, so that it can vectorise the loop.
Would something like this do the same thing?
void addFP(int N, float *in1, float *in2, std::unique_ptr<float> out)
{
for (i = 0 ; i < N; i++)
{
out[i] = in1[i] + in2[i];
}
}
If this does work, which is the more portable choice?
tl;dr Can std::unique_ptr be used to replace the restrict keyword in a loop you're trying to auto-vectorise?
restrict is not part of C++11, instead it is part of C99.
std::unique_ptr<T> foo; is telling your compiler: I only need the memory in this scope. Once this scope ends, free the memory.
restrict tells your compiler: I know that you can't know or proof this, but I pinky swear that this is the only reference to this chunk of memory that occurs in this function.
unique_ptr doesn't stop aliases, nor should the compiler assume they don't exist:
int* pointer = new int[3];
int* alias = pointer;
std::unique_ptr<int> alias2(pointer);
std::unique_ptr<int> alias3(pointer); //compiles, but crashes when deleting
So your first version is not valid in C++11 (though it works on many modern compilers) and the second doesn't do the optimization you are expecting. To still get the behavior concider std::valarray.
I don't think so. Suppose this code:
auto p = std::make_unique<float>(0.1f);
auto raw = p.get();
addFP(1, raw, raw, std::move(p));
This seems like it ought to be obvious, but I'm blanking on it. I have
class SimpleMemoryPool {
char buffer[10000];
size_t idx;
void *Alloc(size_t nbytes) { idx += nbytes; return &buffer[idx - nbytes]; }
};
inline void* operator new (size_t size, SimpleMemoryPool& pool)
{
return pool.Alloc(size);
}
inline void* operator new[] (size_t size, SimpleMemoryPool& pool)
{
return pool.Alloc(size);
}
The idea is that I can allocate new objects out of my SimpleMemoryPool and then they'll all be "released" when the SimpleMemoryPool is destroyed:
void foo()
{
SimpleMemoryPool pool;
int *arr = new (pool) int[10];
double *arr2 = new (pool) double(3.14);
...do things with arr and arr2...
return; // and arr, arr2 are "released" at this point
}
One nitpick I've simplified away: The above code is sketchy because the double won't be 8-byte-aligned. Don't worry about that; my real SimpleMemoryPool code returns maxaligned chunks.
Here's the next thing you're probably thinking at this point: "Who calls the destructors?!" I.e., if I accidentally write
std::string *arr3 = new (pool) std::string;
then I'm in a world of hurt, because the compiler will generate a call to std::string::string() for me, but nobody will ever call std::string::~string(). Memory leaks, bad stuff follows.
This is the problem I want to solve. What I want to do is basically
class SimpleMemoryPool {
...
// (std::enable_if omitted for brevity)
template<typename T, typename... Args>
T *New(Args... args) {
static_assert(std::is_trivially_destructible<T>::value, "T must be trivially destructible!");
void *ptr = this->Alloc(nelem * sizeof (T));
return new (ptr) T(std::forward<Args>(args)...);
}
template<typename ArrayT>
auto NewArray(size_t nelem) -> std::remove_extent<ArrayT>::type {
typedef typename std::remove_extent<ArrayT>::type T;
static_assert(std::is_trivially_destructible<T>::value, "T must be trivially destructible!");
void *ptr = this->Alloc(nelem * sizeof (T));
return new (ptr) T[ nelem ];
}
};
...
int *arr = pool.NewArray<int>(10);
double *arr2 = pool.New<double>(3.14);
std::string *arr3 = pool.New<string>(); // fails the static_assert, hooray!
The problem with this approach is that it's ugly. It looks bad, and it invites later maintainers to come along and "fix" the code by adding a "proper" operator new, at which point we lose the safety of the static_assert.
Is there any way to get the best of both worlds — type-safety via the static_assert, and also a nice syntax?
You may assume C++11. I also welcome C++14 answers, even though they won't be immediately useful to me.
Adding a member operator new to all my classes (in this example int and double) is not acceptable. Whatever I do has to work out-of-the-box without changing a million lines of code.
This is probably a duplicate of Get type of object being allocated in operator new but I'd still like answers tailored to this particular use-case. There might be some nice idiom of which I'm not aware.
i'm using vc++ 2013 express edition.
I'm studying some new feature of c++11 like std::async, and std::future.
I have a class Foo, with an std::shared_ptr<std::vector<unsigned int> >.
In Foo ctor i use std::make_shared to allocate in the heap the vector;
From Foo.h
Class Foo{
public:
Foo();
private:
std::shared_ptr<std::vector<unsigned int> > testVector;
unsigned int MAX_ITERATIONS = 800000000;
void fooFunction();
}
From Foo.cpp
Foo::Foo(){
testVector = std::make_shared<std::vector<unsigned int> >();
//fooFunction(); this take about 20 sec
std::async(std::launch::async, &Foo::fooFunction, this).get(); // and this about the same!!
}
void Foo:fooFunction(){
for (unsigned int i = 0; i < MAX_ITERATIONS; i++){
testVector->push_back(i);
}
}
Th problem is i can't see any gain between calling std::async(std::launch::async, &Foo::fooFunction, this).get(); and fooFunction();
Why??
Any help will be appreciated.
Best regards
std::async returns a std::future.
Calling get() on the future will make it wait until the result is available, then return it. So, even if it is run asynchronously, you are doing nothing but waiting for the result.
std::async doesn't magically parallelize the for loop in Foo::fooFunction.