Template printing member variable without an object - c++

This is weird (MSVC2012):
using namespace std;
class MyClass
{
public:
int membervar;
};
template< int (MyClass::*var) > struct A
{
void print()
{
cout << var;
}
};
int main(int argc, char *argv[])
{
struct A <&MyClass::membervar> object;
object.print();
}
This code compiles and actually couts "1". Where does it get it?? What object does the membervar belong to? I thought I needed an object to access a data member

This code compiles and actually couts "1". Where does it get it?
What happens is that in:
int (MyClass::*var) = &MyClass::membervar;
cout << var;
Because there is no shift operator that takes a stream and a member pointer, another shift operator gets chosen:
std::ostream::operator<<(bool);
In other words, it prints var after converting it to bool.

This code compiles and actually couts "1". Where does it get it??
What you are trying to print is a pointer to a member function.
It's getting converted to a bool. And that bool is evaluating as true, meaning it's non-zero.

Related

C++ : Assigning 2 constructors with 2 different variables doesn't work

I wrote 2 contructors in my program with 2 different variables . However when calling them in main() I get an error saying :
main.cpp:23:11: error: no match for call to '(Basis) (const char [5])'
a("test");
This is my program :
#include <iostream>
using namespace std;
enum Test{Mo,Di};
class Basis
{
public:
Basis(std::string str) { cout << str; }
Basis(Test a)
{
cout << a;
}
};
int main()
{
Basis a(Di);
a("test"); //Error here
return 0;
}
Shouldn't this be working ? I'm assigning for each constructor its own variable .
The line where you have //Error here is not calling a constructor (since a is already instantiated).
Maybe you want something like this to create a second instance of Basis (thus calling the constructor you're wanting):
int main()
{
Basis a(Di);
Basis b("test"); //calls std::string constructor here
return 0;
}
The class Basis and its overloaded constructors are fine. The error is that
the code tries to call the parentheses operator method of the class.
And as there is no such method it thus provides the error you had documented.
Using parentheses to construct an object only works when you are first declaring it.
You can't reconstruct the object the variable is holding, however you can set the variable to a new object of that class. Like Elijay had stated.
a = Basis("test"); // Sets the variable
Well I guess this here answers my question . Dunno why no one mentioned it .
Just had to add a void operator to my public class
#include <iostream>
using namespace std;
enum Test{Mo,Di};
class Basis
{
public:
Basis(Test a)
{
cout << a;
}
void operator()(std::string str )
{
cout << str;
}
};
int main()
{
Basis a(Di);
a("test");
return 0;
}
This will print
1test

Constructor with bool param allows Java-esque code to compile

This blew my mind today until I realized it only compiles with boolean params.
#include <iostream>
using namespace std;
class Foo {
bool _param;
public:
Foo(bool param) {
_param = param;
}
void say() {
cout << "Param is "<< _param << endl;
}
};
int main() {
Foo foo = new Foo(true);
foo.say();
return 0;
}
I also noticed that the constructor is invoked twice, then my guess is that the pointer created by "new Foo(true)" is being casted to a boolean. Is that it? If so, why it does not work with other parameter types? Is there anything else that I'm not seeing?
Foo foo = new Foo(true);
is equivalent to
Foo foo(new Foo(true));
and the pointer result of new turns into true.
That's why it compiles, and you have a memory leak.
I'll add to πάντα ῥεῖ's answer. The reason it (seemingly) only works with bool, is that pointers could be used since the dawn of c as boolean operands. So the implicit conversion must exist.

std::cout changing the variable value

I was coding my function is properly returning a pointer to a reference.
I found that although the function was returning what it was suppose to do, however, std::cout was modifying the results.
Am I doing anything wrong here?
How to rectify this behaviour?
Please refer the following code snippet,
#include "stdafx.h"
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass(int x_):m_Index(x_){}
int m_Index;
};
void myfunction(int *&currentIndex, MyClass obj)
{
currentIndex = &obj.m_Index;
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass obj(5);
int *Index = NULL;
myfunction(Index, obj);
int curr_Index = *Index;
cout << "Index = " << curr_Index << std::endl; // This works fine.
cout << "Index = " << *Index << std::endl; // This modifies *Index
return 0;
}
void myfunction(int *&currentIndex, MyClass obj)
{
currentIndex = &obj.m_Index;
}
Invokes undefined behavior because obj is only valid for the life of the function call. You keep a pointer to it (or one of it's members) which you use AFTER it has gone out of scope.
You can solve either by pointing to something that doesn't go out of scope (see #songyuanyao's answer). In this case it isn't clear why you need pointers. myfunction could just return the index.
The obj parameter is passed by value, so a copy is made that will be destroyed when the function exits. currentIndex is being set to point to an invalid address, and dereferencing it is undefined behavior. It might work well, or it might not work, anything is possible.
One solution is to make obj be passed by reference instead of by value:
void myfunction(int *&currentIndex, MyClass& obj)
{
currentIndex = &obj.m_Index;
}

Error in accessing a 2D array inside a class

I have been working on a code in C++. But, I got stuck at a point.
This is a small prototype of my code::
#include <iostream>
using namespace std;
class Test{
private:
const int var;
void funPrivate(int arr[][var], int temp){
cout << arr[0][0] << endl;
}
public:
Test(int n) : var(n){};
void funPublic(){
int a[var][var];
funPrivate(a, var);
cout << "Hello";
};
};
int main()
{
Test t1(5);
t1.funPublic();
return 0;
}
I create a class funPublic() method, where I create a 2D array (using the const int var, which I declare as a private member inside my class Test) and then pass it to a private methode funPrivate(int arr[][var], int temp), where I print arr[0][0] (which shall be a garbage value).
But, when I try to run this program, I get an error::
error: invalid use of non-static data member 'Test::var'
My method funPrivate(int arr[][var], int temp) is a normal function (not a static function) and I don't a reason that I shall declare int var as static. Why does this happen.
Further, if I slightly modify the declaration of my method 'funPrivate(int arr[][var], int temp)' to this void funPrivate(int arr[][var]) then I get one more error:
error: 'arr' was not declared in this scope
Now, I don't know why does that happen. We pass the size of the array for our convenience, because there is no way to determine the size of the array in a function, but that shall not cause the error that arr was not declared in this scope.
I have been thinking and searching a lot, but still can't find an answer. Please help. Thanks for any help in advance. :D
The member variable var cannot be used in the declaration of an array like you are attempting in the function funPrivate:
void funPrivate(int arr[][var], int temp)
Your best option is to use std::vector<std::vector<int>>.
void funPrivate(std::vector<std::vector<int>> const& arr, int temp) {
cout << arr[0][0] << endl;
}
In the calling function, you can use:
void funPublic(){
std::vector<std::vector<int>> arr(var, std::vector<int>(var));
funPrivate(arr, var);
cout << "Hello";
};

What exactly is the ->* operator?

I've never used it before and just stumbled upon it in an article... I thought it would be the equivalent to *x->y but apparently it isn't.
Here's what I tried, and gave me an error:
struct cake {
int * yogurt;
} * pie;
int main(void) {
pie = new cake;
pie->yogurt = new int;
return pie->*yogurt = 4;
}
Its used when you have pointers to member functions.
When you have a pointer to a function of a class, you call it in much the same way you would call any member function
object.membername( ... )
or
objectptr->membername( ... )
but when you have a member function pointer, an extra * is needed after the . or -> in order that the compiler understand that what comes next is a variable, not the actual name of the function to call.
Here's an example of how its used.
class Duck
{
public:
void quack() { cout << "quack" << endl; }
void waddle() { cout << "waddle" << endl; }
};
typedef void (Duck::*ActionPointer)();
ActionPointer myaction = &Duck::quack;
void takeDuckAction()
{
Duck myduck;
Duck *myduckptr = &myduck;
(myduck.*myaction)();
(myduckptr->*myaction)();
}
It defines a pointer to a member.
In an expression containing the –>* operator, the first operand must
be of the type "pointer to the class type" of the type specified in
the second operand, or it must be of a type unambiguously derived from
that class.
MSDN
Pointer-to-Member Operators: .* and ->*
The .* and ->* operators will point to member functions of a class or structure. The code below will show a simple example of how to use the .* operator, if you change the line:
Value funcPtr = &Foo::One; to Value funcPtr = &Foo::Two; the result displayed will change to 1000 since that function is inValue*2
for example Taken From Here:
#include <iostream>
#include <stdlib.h>
class Foo {
public:
double One( long inVal ) { return inVal*1; }
double Two( long inVal ) { return inVal*2; }
};
typedef double (Foo::*Value)(long inVal);
int main( int argc, char **argv ) {
Value funcPtr = &Foo::One;
Foo foo;
double result = (foo.*funcPtr)(500);
std::cout << result << std::endl;
system("pause");
return 0;
}