how to make a field of a constexpr object constexpr too? - c++

cube is a class that from what i know can be both constexpr and not and for some reason c.get() is not constexpr because the second cout prints 5 which mean it changed the value of c to 5 instead of c.get() always returning 1.
class cube
{
private:
int roll;
public:
constexpr cube(const int& r) :roll(r) {}
void set(int const& a) { roll = a; }
constexpr int get() const { return roll; }
constexpr void fun() const
{
(const_cast <cube*> (this))->roll = 5;
}
};
int main()
{
constexpr cube c(1);
std::cout << "Old roll number: " << c.get() << std::endl;
c.fun();
std::cout << "New roll number: " << c.get() << std::endl;
return 0;
}
EDIT:
in the comments some said that the fun() breaks it but here it's still not constexpr as you can see here gcc.godbolt.org/z/zoz7KEqqn
#include<iostream>
class cube
{
private:
int roll;
public:
constexpr cube(const int& r) :roll(r) {}
void set(int const& a) { roll = a; }
constexpr int get() const { return roll; }
};
int main()
{
constexpr cube c(1);
std::cout << "Old roll number: " << c.get() << std::endl;
std::cout << "New roll number: " << c.get() << std::endl;
return 0;
}

Related

Static Cast to CRTP Interface [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 1 year ago.
I am building up a CRTP interface and noticed some undefined behavior. So, I built up some sample code to narrow down the problem.
#include <iostream>
template <typename T>
class Base {
public:
int a() const { return static_cast<T const&>(*this).a_IMPL(); }
int b() const { return static_cast<T const&>(*this).b_IMPL(); }
int c() const { return static_cast<T const&>(*this).c_IMPL(); }
};
class A : public Base<A> {
public:
A(int a, int b, int c) : _a(a), _b(b), _c(c) {}
int a_IMPL() const { return _a; }
int b_IMPL() const { return _b; }
int c_IMPL() const { return _c; }
private:
int _a;
int _b;
int _c;
};
template <typename T>
void foo(const T& v) {
std::cout << "foo()" << std::endl;
std::cout << "a() = " << static_cast<Base<T>>(v).a() << std::endl;
std::cout << "b() = " << static_cast<Base<T>>(v).b() << std::endl;
std::cout << "c() = " << static_cast<Base<T>>(v).c() << std::endl;
}
int main() {
A v(10, 20, 30);
std::cout << "a() = " << v.a() << std::endl;
std::cout << "b() = " << v.b() << std::endl;
std::cout << "c() = " << v.c() << std::endl;
foo(v);
return 0;
}
The output of this code is:
a() = 10
b() = 20
c() = 30
foo()
a() = 134217855
b() = 0
c() = -917692416
It appears that there is some problem when casting the child class, which implements the CRTP "interface", to the interface itself. This doesn't make sense to me because the class A plainly inherits from Base so, shouldn't I be able to cast an instance of A into Base?
Thanks!
You copy and slice when you cast to Base<T>.
Cast to a const Base<T>& instead:
std::cout << "a() = " << static_cast<const Base<T>&>(v).a() << std::endl;
std::cout << "b() = " << static_cast<const Base<T>&>(v).b() << std::endl;
std::cout << "c() = " << static_cast<const Base<T>&>(v).c() << std::endl;
It turns out I was casting incorrectly to a value rather than a reference
std::cout << "a() = " << static_cast<Base<T>>(v).a() << std::endl;
should become
std::cout << "a() = " << static_cast<const Base<T>&>(v).a() << std::endl;

Function don't work in the class (c++)

Newly I've begun learning OOP.I've written simple program.But function int sum() has errors.Can you write decision of the problem.And explain errors.
class Int
{
private:
int num;
public
Int()
{
num = 0;
}
Int(int n)
{
num = n;
}
int getValue()
{
return num;
}
int sum(const Int& n)
{
return num+ n.getValue();
}
void main()
{
short a, b;
cout << "Enter 2 numbers:";
cin >> a >> b;
Int A(a), B(b), res;
cout << A.getValue() << " + " << B.getValue() << " = " << A.sum(B) <<"\n\n";
}
Below is my attempt. There were some formatting issues but the trickiest problem was that getValue() is a const function.
class Int {
private:
int num;
public:
Int() { num = 0; }
Int(int n) { num = n; }
// getValue is a const function as it does not alter object 'n'.
int getValue() const { return num; }
int sum(const Int& n) {
int ret = num + n.getValue();
return ret;
}
};
int main() {
int a, b;
std::cout << "Enter 2 numbers:";
std::cin >> a >> b;
Int A(a), B(b), res;
std::cout << A.getValue() << " + " << B.getValue() << " = " << A.sum(B) << "\n\n";
}
You cannot declare a function inside another function like that. You have main() inside sum().

Can I specify or select a member of a class (and use it as parameter )?

For example, let's say I have:
class AB { float a,b; };
How do I write one function that can process either a or b, based on a parameter that's passed in, in a "proper" way? I want to do something like this:
float getSqrt(AB x, ClassMemberSelector s)
{ return sqrt(x.s); }
AB x;
getSqrt(x, SelectClassMember(AB::a) ); //get square root of x.a
getSqrt(x, SelectClassMember(AB::b) ); //get square root of x.b
Sure, here are three examples:
1)
float getSqrt(const AB& ab, function<float(const AB&)> selector)
{
return sqrt(selector(ab));
}
which simplifies to (thanks to NathanOliver's comment):
template<typename SelectorT>
float getSqrt(AB ab, SelectorT selector)
{
return sqrt(selector(ab));
}
(this version is better, as it avoids copying a lambda into std::function)
and usage (same for both versions):
cout << getSqrt(x, [](const AB& ab) { return ab.a; }) << endl;
cout << getSqrt(x, [](const AB& ab) { return ab.b; }) << endl;
2)
Another possibility would be to use a pointer to member:
float getSqrt(const AB& ab, float AB::*selector)
{
return sqrt(ab.*selector);
}
and usage:
cout << getSqrt(x, &AB::a) << endl;
cout << getSqrt(x, &AB::b) << endl;
3)
And an example using TMP trait-like overload selection:
struct SelectAMemberT {};
struct SelectBMemberT {};
template<typename SelectorT>
float getSqrt(const AB& ab, SelectorT);
template<>
float getSqrt(const AB& ab, SelectAMemberT)
{
return sqrt(ab.a);
}
template<>
float getSqrt(const AB& ab, SelectBMemberT)
{
return sqrt(ab.b);
}
const SelectAMemberT SelectAMember;
const SelectBMemberT SelectBMember;
and usage:
cout << getSqrt(x, SelectAMember) << endl;
cout << getSqrt(x, SelectBMember) << endl;
#include <iostream>
#include <cmath>
class AB
{
public:
float a, b;
};
float getSqrt(AB x, float AB::*mem)
{
return sqrt(x.*mem);
}
int main()
{
AB x;
x.a = 9;
x.b = 16;
std::cout << "sqrt x.a: " << getSqrt(x, &AB::a) << std::endl;
std::cout << "sqrt x.b: " << getSqrt(x, &AB::b) << std::endl;
system("pause");
return 0;
}

How to invoke this member function in C++?

Is it possible to call this member int MyClass::get(int key) const instead of the int& MyClass::get(int key)? In other words, where in the C++ source codes, a value can be used but not a reference?
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass(int input) : i(input) {};
int i;
int get(int key) const {
std::cout << "int get(int key) const " << key << std::endl;
return i;
}
int& get(int key) {
std::cout << "int& get(int key) " << key << std::endl;
return i;
}
};
void dummy(const int helpme)
{
std::cout << helpme << std::endl;
}
int main() {
// your code goes here
MyClass abc(6);
std::cout << abc.get(13) << std::endl;
int result = (int)abc.get(16);
dummy(abc.get(18));
return 0;
}
The simplest solution is to use a const & to your variable. Two simple ways are
const auto & abc_const = abc;
std::cout << abc_const.get(13) << std::endl;
or
std::cout << static_cast<const MyClass&>(abc).get(13) << std::endl;
Edit: It looks like you were trying to choose an overload based on the return type, based on these two lines :
int result = (int)abc.get(16);
dummy(abc.get(18));
See this answer explaining how the return type is never used during overload resolution.

dynamic_cast vs static_cast to void*

In the last two lines of below program, static_cast<void*> and dynamic_cast<void *> behave differently. From what I understand, The result of a dynamic_cast<void*> always resolves to the address of the complete object. So it uses RTTI in some way. Could anyone explain how compilers uses RTTI to differentiate between the two.
#include <iostream>
using namespace std;
class Top {
protected:
int x;
public:
Top(int n) { x = n; }
virtual ~Top() {}
friend ostream& operator<<(ostream& os, const Top& t) {
return os << t.x;
}
};
class Left : virtual public Top {
protected:
int y;
public:
Left(int m, int n) : Top(m) { y = n; }
};
class Right : virtual public Top {
protected:
int z;
public:
Right(int m, int n) : Top(m) { z = n; }
};
class Bottom : public Left, public Right {
int w;
public:
Bottom(int i, int j, int k, int m): Top(i), Left(0, j), Right(0, k) { w = m; }
friend ostream& operator<<(ostream& os, const Bottom& b) {
return os << b.x << ',' << b.y << ',' << b.z<< ',' << b.w;
}
};
int main() {
Bottom b(1, 2, 3, 4);
cout << sizeof b << endl;
cout << b << endl;
cout << static_cast<void*>(&b) << endl;
Top* p = static_cast<Top*>(&b);
cout << *p << endl;
cout << p << endl;
cout << static_cast<void*>(p) << endl;
cout << dynamic_cast<void*>(p) << endl;
return 0;
}
Possible output: https://ideone.com/WoX5DI
28
1,2,3,4
0xbfcce604
1
0xbfcce618
0xbfcce618
0xbfcce604
From 5.2.7 / 7:
If T is "pointer to cv void," then the result is a pointer to the most
derived object pointed to by v. Otherwise, a run-time check is applied
to see if the object pointed or referred to by v can be converted to
the type pointed or referred to by T.
So using dynamic_cast<void*>(o) you get a pointer to the first byte of the most "derived" object (if o is polymorphic).
The code the compiler generates for dynamic_cast<void *>(...) is something like:
static_cast<void*>(dynamic_cast<most_derived_type *>(...))
This property is often used for serialization.