Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
The problem is to implement class Cplx with two doubles x and y represent real and imaginary part of complex numbers.
One of the subtask is to implement operator -> with following description:
(z->re and z->im): access to the real and imaginary part of z(You must implement changing like z->re = 5).
I have troubles with operator -> I never really understand how it works so my question is: how -> works and when to use it and how to apply that idea in this problem.
The following does what you ask... But not sure it is what you want:
template <typename T>
struct ReIm
{
const ReIm* operator ->() const { return this; }
ReIm* operator ->() { return this; }
T re;
T im;
};
struct Cplx
{
double x;
double y;
ReIm<double> operator ->() const { return {x, y}; }
ReIm<double&> operator ->() { return {x, y}; }
};
Demo
The -> operator works to dereference a pointer to an object and get a member variable/function in one operator. For example,
Cplx* cplxPointer = new Cplx();
cplxPointer->x = 5;
Is the same as
Cplx* cplxPointer = new Cplx();
(*cplxPointer).x = 5;
It just dereferences the pointer and then gets the member variable (or function if you want). Unless I misunderstood your question, the above should be able to help you complete your assignment.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Apologies for the most ambiguous and bizarre title.
Suppose we have 2 classes A and B.
class B has interface hasSmth but class A has not.
How to make this code evaluate without compile errors?
class A {
//..implementation
int id() { return 1; }
};
class B {
//..implementation
int id() { return 2; }
bool hasSmth() { return true; }
};
int main()
{
auto obj = someFunction();//returns A or B
if (obj.id() == 1 || (obj.id() == 2 && obj.hasSmth())) {
...
}
}
If the function returns obj of type B, then we are good.
But if it returns obj of type A, compiler will complain about A not having hasSmth, regardless of that part of if never been evaluated.
Can someone give a workaround please?
Can someone give a workaround please?
Read the declaration of someFunction to see what it returns. In the case it doesn't return B, then don't write obj.hasSmth(). Problem solved.
Now, let's change the question a bit. Let's say that you want to make this work without knowing the return type. Perhaps because rather than main you may be actually writing a template that works with different types. There are several approaches, but function overloads are a simple one:
bool check([[maybe_unused]] const A&) {
return true;
}
bool check(const B& b) {
return b.hasSmth();
}
template<bool returnsA>
void foo() {
auto obj = someTemplate<returnsA>(); // returns A or B
if (check(obj)) {
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am writing a wrapper around a C-API.
(i) Let capi_array_data capi_get_array(void) be a function contained within this library returning a struct containing metadata about a heap-allocated array managed by said API. It would look something like struct capi_get_array { size_t length; int* arr }; (using int for simplicity)
(ii) Such an array can be created by the user manually with malloc, new, std::vector, etc. It must then be registered with void capi_register_array(int*).
I want to make a wrapper class, call it MyArrayWrapper, managing such an array with the anatomy of an STL container, supporting operator[], begin, back, etc. In (i) this wrapper would not own the data, but in (ii) it would. My question now is, whether I should
(a) have one single class that can be constructed using either a std::initializer_list (or variadic template for that matter) or an int* returned by the API;
(b) have separate classes named something like MyArrayWrapperRef and MyArrayWrapper, the first handling (i) and the second handling (ii);
(c) optimally have the syntax MyArrayWrapper& for (i) and MyArrayWrapper for (ii); can this be done?
With (a) there could come up confusion, as one class does two things, which breaks the single-responsibility principle. Answers to questions like "does the copy constructor conduct a deep of shallow copy?" will not be obvious and would require further documentation.
(b) seems like a good choice, but now there are multiple cases: MyArrayWrapper, MyArrayWrapper&, MyArrayWrapperRef, MyArrayWrapperRef&. How would they differ? What about const references? This might even require another class MyArrayWrapperConstRef and again leads to confusion.
(c) is optimal and seems natural with other classes, but I don't know of a way to make it work. I could make a wrapper around capi_get_array returning a MyArrayWrapperRef, but I would have to save the source of the reference somewhere, right?
With (a) there could come up confusion, as one class does two things,
which breaks the single-responsibility principle.
You can also see it the other way around: The single responsibility of the wrapper is to hide the real ownership and who cleans up what.
Lets say you have this:
struct arr_data {
int* a;
unsigned size;
};
arr_data get_arr(){
arr_data ret;
ret.size = 5;
ret.a = new int[ret.size];
return ret;
}
void reg_arr(arr_data x){
static arr_data store = x;
}
Then a simple wrapper could look like this:
struct wrapper {
std::shared_ptr<arr_data> data;
// implement container-like interface
};
wrapper make_non_owning_wrapper() {
auto res = new arr_data();
*res = get_arr();
return { std::shared_ptr<arr_data>(res,[](arr_data* x){
std::cout << "delete x only\n";
delete x;
}) };
}
wrapper make_owning_wrapper() {
auto res = new arr_data();
res->size = 5;
res->a = new int[res->size];
return { std::shared_ptr<arr_data>(res,[](arr_data* x){
std::cout << "delete both\n";
delete[] x->a;
delete x;
})};
}
int main(){
auto v = make_owning_wrapper();
auto w = make_non_owning_wrapper();
auto z = v;
}
Using a shared pointer you can choose a) what to do on clean up and b) what happens when copying a wrapper without causing great confusion ;).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
My class has an array of objects, call it Foo. It is stored as Foo* m_Foos in the class. Say it has a value at [0], guaranteed, and Foo has a property called IsSetthat's just a bool or something.
void TryThis()
{
Foo returnValue;
GetValue(returnValue);
returnValue.IsSet = true;
if(m_Foo[0].IsSet != returnValue.IsSet)
{
// ERROR!!!!
}
}
void GetValue(Foo &container)
{
container = m_Foos[0];
}
Can anyone explain why m_Foo[0] =/= returnValue? Where is the error in my syntax?
I expect m_Foo[0] to be the same reference as returnValue, the same Foo in memory.
TryThis() is not modifying the Foo object that is stored in the m_Foos array.
GetValue() is assigning the Foo object from m_Foos[0] to another Foo object that is local to TryThis(). A copy is being made during that assigment. TryThis() is then modifying the copy, not the original.
If you want TryThis() to modify the original Foo object directly, you need to do something more like this instead:
void TryThis()
{
Foo &returnValue = GetValue();
returnValue.IsSet = true;
// m_Foo[0] is set true.
}
Foo& GetValue()
{
return m_Foos[0];
}
Or this:
void TryThis()
{
Foo *returnValue;
GetValue(returnValue);
returnValue->IsSet = true;
// m_Foo[0] is set true.
}
void GetValue(Foo* &container)
{
container = &m_Foos[0];
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
i find this construction:
std::map<T, T> a = boost::assign::map_list_of(arg11, arg12)
(arg21, arg22)
;
Please, tell what happens in this and how to realize it on c++?
I didn't read the implementation, bu I think you can reproduce that with a "Accumulator" object :
template<class T>
class Acc
{
public:
Acc &operator()(T a, T b)
{
map.insert(std::make_pair(a, b));
}
operator std::map<T, T>()
{
return map;
}
private:
std::map<T, T> map;
}
Each time you do something like (a,b), you call the operator(), which just add the std::pair(a, b) inside the map. The cast operator allow to get a std::map instead of the Acc object.
The use is :
std::map<int, int> = Acc<int>()(1,2)(3,4)(6,7);
Nb : Code not tested.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a class A and it has two method foo which are actually overloaded. The class somewhat look like this
class A
{
public:
bool foo(int& a);
bool foo(size_t& a);
};
bool A::foo(int& a)
{
return true;
}
bool A::foo(size_t& a)
{
int new_a = a;
return foo(new_a); // here Cl throws me warning C4717: 'hweudm::UDMAbstractBaseEntity::SetAttribute' : recursive on all control paths, function will cause runtime stack overflow
}
int main()
{
A aObj;
size_t val = 12;
aObj.foo(val);
return 0;
}
From the code it does not look ambiguous. But I don't want to this warning during compilation. So can Anyone tell me
Why I am getting this warning even though I have type casted size_t to int ?
whether this will be be an error not a warning on GCC.
The code isn't correct. The result of the conversion-cast (int)a is an rvalue, and it cannot bind to either lvalue reference.
The only thing that would come close, if it weren't horribly undefined behaviour, would be something like foo(reinterpret_cast<int &>(a)), but don't do this, since it is not correct.
isn't size_t:
typedef unsigned int size_t;
? then A::foo(int& a) and A::foo(size_t& a) are exactly the same thing