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.
Related
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;
}
I have class A which has methods void fun(int, int) and void fun1(int, int). These are non-static methods.
struct A {
void fun(int,int){}
void fun1(int,int){}
};
Now inside class B I want to store pointer to one of the method.
Which means object1 of B will have pointer to fun and object2 of B will have pointer to fun1.
Now my set_handler() and pointer to handler has to be generic.
One way is to use function pointers.
So that that I can use void(A::*pointer)(int,int) which can store address of fun or fun1.
struct B {
typedef void(A::*pointer)(int,int);
pointer f;
void set_handler(pointer p) { f = p; }
};
int main() {
{
B object1;
object2.set_handler(&A::fun);
}
{
B object2;
object2.set_handler(&A::fun1);
}
}
I was looking into boost::bind() but it needs specific name. How do I use boost here?
I malled your question into running code that actually does something with the pointer - so we know when the goal has been achieved:
Live On Coliru
#include <iostream>
struct A {
void fun(int a, int b) { std::cout << __FUNCTION__ << "(" << a << "," << b << ")" << std::endl; }
void fun1(int a, int b) { std::cout << __FUNCTION__ << "(" << a << "," << b << ")" << std::endl; }
};
struct B {
typedef void (A::*pointer)(int, int);
pointer f;
void set_handler(pointer p) { f = p; }
void run(A& instance) {
(instance.*f)(42, 42);
}
};
int main() {
B object1;
B object2;
object1.set_handler(&A::fun);
object2.set_handler(&A::fun1);
A a;
object1.run(a);
object2.run(a);
}
Prints
fun(42,42)
fun1(42,42)
Using boost::function or std::function
You have to allow for the instance argument (the implicit this parameter):
Live On Coliru
struct B {
using function = std::function<void(A&, int, int)>;
function f;
void set_handler(function p) { f = p; }
void run(A& instance) {
f(instance, 42, 42);
}
};
Which prints the same output. Of course you can use boost::function and boost::bind just the same
What about bind?
Bind comes in when you want to adapt the function signatures. So, e.g. you want to bind to any instance of A& without actually passing it into run():
Live On Coliru
#include <iostream>
#include <functional>
struct A {
std::string name;
void fun(int a, int b) { std::cout << "name:" << name << " " << __FUNCTION__ << "(" << a << "," << b << ")" << std::endl; }
void fun1(int a, int b) { std::cout << "name:" << name << " " << __FUNCTION__ << "(" << a << "," << b << ")" << std::endl; }
};
struct B {
using function = std::function<void(int, int)>;
function f;
void set_handler(function p) { f = p; }
void run() {
f(42, 42);
}
};
int main() {
B object1;
B object2;
A a1 {"black"};
A a2 {"white"};
{
using namespace std::placeholders;
object1.set_handler(std::bind(&A::fun, &a1, _1, _2));
object2.set_handler(std::bind(&A::fun1, &a2, _1, _2));
}
object1.run();
object2.run();
}
Which prints:
name:black fun(42,42)
name:white fun1(42,42)
More Goodness
From c++ you can do without bind and its pesky placeholders (there are other caveats, like bind storing all arguments by value). Instead, you may use lambdas:
Live On Coliru
#include <iostream>
#include <functional>
struct A {
std::string name;
void fun(int a, int b) { std::cout << "name:" << name << " " << __FUNCTION__ << "(" << a << "," << b << ")" << std::endl; }
void fun1(int a, int b) { std::cout << "name:" << name << " " << __FUNCTION__ << "(" << a << "," << b << ")" << std::endl; }
};
struct B {
using function = std::function<void(int, int)>;
function f;
void set_handler(function p) { f = p; }
void run() {
f(42, 42);
}
};
int main() {
B object1;
B object2;
object1.set_handler([](int a, int b) {
A local_instance {"local"};
local_instance.fun(a*2, b*3); // can even do extra logic here
});
A main_instance {"main"};
object2.set_handler([&main_instance](int a, int b) {
main_instance.fun1(a, b); // can even do extra logic here
});
object1.run();
object2.run();
}
Prints
name:local fun(84,126)
name:main fun1(42,42)
I have a class with a reference and want a getter that returns a pointer.
class X {
std::string& text;
public:
auto GetText() -> decltype(text) * { return &text); // doesn't work
X(std::string& text): text(text) {}
};
The easy way is to pass a pointer to this class. But if I pass a reference, can I get a pointer with a getter?
Edit: here is the error message
error: cannot declare pointer to 'std::__cxx11::string& {aka class std::__cxx11::basic_string<char>&}'
auto GetText() -> decltype(text) * { return &text);
^
Firstly,
auto GetText() -> decltype(text) * { return &text); // doesn't work
is a positively abominable way to declare this signature. Prefer
std::string* GetText(){ return &text);
or even just
auto GetText(){ return &text);
But this isn't code review.
The problem here is that you're asking for a pointer to the declared type of the text member variable which is a string reference (std::string&). From the comment section, it seems you were unaware that decltype respects the 'reference'ness, 'const'ness, and 'volatile'ness of its argument.
You cannot have a pointer to a reference in C++, e.g. std::string&* is malformed. Calling to std::remove_reference_t should resolve that issue, e.g.
auto GetText() -> std::remove_reference_t<decltype(text)> * { return &text);
However, in this case, auto would have correctly deduced your type anyway, so your explicit declaration is unnecessary.
I've made a test program for my initial problem. The program has a class with a pointer and a getter that returns a reference and a second class with a reference and a getter that returns a pointer.
And it seems that -> std::remove_reference_t<decltype(text)> can be substituted with -> decltype(&text).
Feel free to comment.
// g++ main.cpp -o test_reference_pointer && strip -s test_reference_pointer && ./test_reference_pointer
#include <iostream>
// A class with a pointer and a getter that returns a reference.
class A {
std::string *text;
public:
std::string& GetText_old_way() { return *text; }
auto GetText_pure_auto() { return *text; }
auto GetText_pointer_arithmetic() -> decltype(*text) & { return *text; }
public:
A(std::string *text): text(text) {}
};
// A class with a reference and a getter that returns a pointer.
class B {
std::string& text;
public:
std::string *GetText_old_way() { return &text; }
auto GetText_pure_auto() { return &text; }
auto GetText_pointer_arithmetic() -> decltype(&text) { return &text; }
auto GetText_remove_reference() -> std::remove_reference_t<decltype(text)> * { return &text; }
public:
B(std::string& text): text(text) {}
};
int main() {
std::string text = "hello, world";
{//TEST
A a(&text);
unsigned int i{0};
std::cout << "-- Test 1:"<< std::endl;
++i; std::cout << i << ". " << a.GetText_old_way() << std::endl;
++i; std::cout << i << ". " << a.GetText_pointer_arithmetic() << std::endl;
++i; std::cout << i << ". " << a.GetText_pure_auto() << std::endl;
std::cout << std::endl;
}
{//TEST
B b(text);
unsigned int i{0};
std::cout << "-- Test 2:"<< std::endl;
++i; std::cout << i << ". " << *b.GetText_old_way() << std::endl;
++i; std::cout << i << ". " << *b.GetText_pointer_arithmetic() << std::endl;
++i; std::cout << i << ". " << *b.GetText_remove_reference() << std::endl;
++i; std::cout << i << ". " << *b.GetText_pure_auto() << std::endl;
std::cout << std::endl;
}
return 0;
}
First off: I know that it is generally a bad idea to change an object's class, but I'm implementing my own programming language, and it has variables that can contain values of any type, and even change their type at will, so please assume I'm not a beginner not understanding OO basics.
Currently, I implement my variant variables in C. Each one has a pointer to a table of function pointers, containing functions like SetAsInt(), SetAsString() etc., followed by what would be instance variables in C++. All objects are the same size.
When a variable contains a string and someone assigns an Int to it, I manually call the destructor, change the table of function pointers to point to the table used for variadic int values, and then set its int instance variable.
This is a bit hard to maintain, as every time I add a new type, I have to add a new table of function pointers and fill out all the function pointers in it. Structs of function pointers seem to be very badly type-checked, and missing fields don't lead to complaints, so I can easily accidentally forget one pointer in the list and get interesting crashes. Also, I have to repeat all the function pointers that are the same in most types.
I'd like to implement my variadic types in C++ instead, where a lot of this type-checking and inheriting default behaviours is done for me by the compiler. Is there a safe way to do this?
PS - I know I could create a wrapper object and use new to allocate a new object, but I can't have the additional extra allocation overhead for every int variable on the stack.
PPS - The code needs to be portable across Linux, Mac, iOS and Windows for now, but if someone has a standard C++ solution, that would be even better.
PPPS - The list of types is extensible, but predetermined at compile-time. The base layer of my language defines just the basic types, but the host application my language is compiled into adds a few more types.
Usage Example:
CppVariant someNum(42); // Creates it as CppVariantInt.
cout << "Original int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsInt(700); // This is just a setter call.
cout << "Changed int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsDouble(12.34); // This calls destructor on CppVariantInt and constructor on CppVariantDouble(12.34).
cout << "Converted to Double: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl; // GetAsInt() on a CppVariantDouble() rounds, or whatever.
(Imagine that beyond double and int, there would be other types in the future, like strings or booleans, but the caller of GetAsInt()/SetAsInt() shouldn't have to know what it is stored as, as long as it can be converted at runtime)
Here is a solution based on type-erasure, union and template specializations.
I'm not sure it fits your requirements.
Anyway, here is what it gets:
Anything is placed on the dynamic storage
No hierarchy required
You can easily improve it further to reduce the amount of code, but this aims to serve as a base point from which to start.
It follows a minimal, working example based on the intended use in the question:
#include<iostream>
class CppVariant {
union var {
var(): i{0} {}
int i;
double d;
};
using AsIntF = int(*)(var);
using AsDoubleF = double(*)(var);
template<typename From, typename To>
static To protoAs(var);
public:
CppVariant(int);
CppVariant(double);
int getAsInt();
double getAsDouble();
void setAsInt(int);
void setAsDouble(double);
private:
var data;
AsIntF asInt;
AsDoubleF asDouble;
};
template<>
int CppVariant::protoAs<int, int>(var data) {
return data.i;
}
template<>
int CppVariant::protoAs<double, int>(var data) {
return int(data.d);
}
template<>
double CppVariant::protoAs<int, double>(var data) {
return double(data.i);
}
template<>
double CppVariant::protoAs<double, double>(var data) {
return data.d;
}
CppVariant::CppVariant(int i)
: data{},
asInt{&protoAs<int, int>},
asDouble{&protoAs<int, double>}
{ data.i = i; }
CppVariant::CppVariant(double d)
: data{},
asInt{&protoAs<double, int>},
asDouble{&protoAs<double, double>}
{ data.d = d; }
int CppVariant::getAsInt() { return asInt(data); }
double CppVariant::getAsDouble() { return asDouble(data); }
void CppVariant::setAsInt(int i) {
data.i = i;
asInt = &protoAs<int, int>;
asDouble = &protoAs<int, double>;
}
void CppVariant::setAsDouble(double d) {
data.d = d;
asInt = &protoAs<double, int>;
asDouble = &protoAs<double, double>;
}
int main() {
CppVariant someNum(42);
std::cout << "Original int: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
someNum.setAsInt(700);
std::cout << "Changed int: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
someNum.setAsDouble(12.34);
std::cout << "Converted to Double: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
}
On a lark, I tried using placement new to do this, and I have ... something ... It compiles, it does the job, but I'm not sure if it's an improvement over pure C. Since I can't have a union of C++ objects, I create a CPPVMAX() macro to pass the largest sizeof() of all subclasses as the size to mBuf[], but that's not really pretty either.
#include <iostream>
#include <string>
#include <cmath>
#define CPPVMAX2(a,b) (((a) > (b)) ? (a) : (b))
#define CPPVMAX3(a,b,c) CPPVMAX2((a),CPPVMAX2((b),(c)))
using namespace std;
class CppVariantBase
{
public:
CppVariantBase() { cout << "CppVariantBase constructor." << endl; }
virtual ~CppVariantBase() { cout << "CppVariantBase destructor." << endl; }
virtual int GetAsInt() = 0;
virtual double GetAsDouble() = 0;
virtual void SetAsInt( int n );
virtual void SetAsDouble( double n );
};
class CppVariantInt : public CppVariantBase
{
public:
CppVariantInt( int n = 0 ) : mInt(n)
{
cout << "CppVariantInt constructor." << endl;
}
~CppVariantInt() { cout << "CppVariantInt destructor." << endl; }
virtual int GetAsInt() { return mInt; }
virtual double GetAsDouble() { return mInt; }
virtual void SetAsInt( int n ) { mInt = n; }
protected:
int mInt;
};
class CppVariantDouble : public CppVariantBase
{
public:
CppVariantDouble( double n = 0 ) : mDouble(n)
{
cout << "CppVariantDouble constructor." << endl;
}
~CppVariantDouble()
{
cout << "CppVariantDouble destructor." << endl;
}
virtual int GetAsInt()
{
if( int(mDouble) == mDouble )
return mDouble;
else
return round(mDouble);
}
virtual double GetAsDouble() { return mDouble; }
virtual void SetAsDouble( int n ) { mDouble = n; }
protected:
double mDouble;
};
class CppVariant
{
public:
CppVariant( int n = 0 ) { new (mBuf) CppVariantInt(n); }
~CppVariant() { ((CppVariantBase*)mBuf)->~CppVariantBase(); }
operator CppVariantBase* () { return (CppVariantBase*)mBuf; }
CppVariantBase* operator -> () { return (CppVariantBase*)mBuf; }
protected:
uint8_t mBuf[CPPVMAX3(sizeof(CppVariantBase),sizeof(CppVariantInt),sizeof(CppVariantDouble))];
};
void CppVariantBase::SetAsInt( int n )
{
this->~CppVariantBase();
new (this) CppVariantInt(n);
}
void CppVariantBase::SetAsDouble( double n )
{
this->~CppVariantBase();
new (this) CppVariantDouble(n);
}
int main(int argc, const char * argv[]) {
CppVariant someNum(42);
cout << "Original int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsInt(700); // This is just a setter call.
cout << "Changed int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsDouble(12.34); // This changes the class to CppVariantDouble.
cout << "Converted to Double: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
return 0;
}
I am trying to write a map of heterogeneous function pointers and have mimicked that in a smaller program which has functions to either take a "int" or a "double" val.
#include <iostream>
#include <boost/any.hpp>
#include <map>
#include <sstream>
using namespace std;
class Functions
{
public:
void intF(int f) { cout << " Value int : " << f << endl; }
void doubleF(double f) { cout << " Value double : " << f << endl; }
};
const boost::any convertInt(const string& s)
{
cout << " string passed : " << s << endl;
std::istringstream x(s);
int i;
x >> i;
cout << " Int val : " << i << endl;
return i;
}
const boost::any convertDouble(const string& s)
{
cout << " string passed : " << s << endl;
std::istringstream x(s);
double i;
x >> i;
cout << " Double val : " << i << endl;
return i;
}
typedef void (Functions::*callFunc)( const boost::any);
typedef const boost::any (*convertFunc)( const string&);
struct FuncSpec
{
convertFunc _conv;
callFunc _call;
};
FuncSpec funcSpec[] = {
{ &convertInt, (callFunc)&Functions::intF },
{ &convertDouble, (callFunc)&Functions::doubleF },
};
int main()
{
string s1("1");
string s2("1.12");
callFunc c = funcSpec[0]._call;
convertFunc co = funcSpec[0]._conv;
Functions F;
(F.*c)(((*co)(s1)));
c = funcSpec[1]._call;
co = funcSpec[1]._conv;
(F.*c)(((*co)(s2)));
return 0;
}
When I run this program, I see the double value getting printed correctly but the int value is garbled. Could someone help me with this? Also is there a better way to achieve this functionality. In my program I have 2 functions - one taking a vector<int> and the other taking a vector<double>. I have to read the data from a file and call the appropriate setters in the object of the class which has these 2 functions.
Casting a member function to a different type like you are doing isn't valid. Try this instead:
class Functions
{
public:
void intF(boost::any input)
{
int f = boost::any_cast<int>(input);
cout << " Value int : " << f << endl;
}
void doubleF(boost::any input)
{
double f = boost::any_cast<double>(input);
cout << " Value double : " << f << endl;
}
};
.
.
.
FuncSpec funcSpec[] = {
{ &convertInt, &Functions::intF },
{ &convertDouble, &Functions::doubleF },
};