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
The C++ draft says that
A non-type template-parameter shall have one of the following
(optionally cv-qualified) types: — integral or enumeration type, —
pointer to object or pointer to function, — lvalue reference to object
or lvalue reference to function, — pointer to member, —
std::nullptr_t.
In the following code I have a pointer to member passed as parameter to a template
using namespace std;
class MyClass
{
public:
int membervar;
};
template< int (MyClass::*var) > struct A
{
// What am I supposed to do with *var? There isn't an object instance to use it!
};
int main(int argc, char *argv[])
{
struct A <&MyClass::membervar> object;
}
The above code compiles (MSVC2012) without errors
The question is: I don't see what am I supposed to do with such a pointer, there isn't an object instance to use it
The only way I can think to answer this is to construct an example:
template< int (MyClass::*var) > struct A
{
A() {
MyClass myclass;
myclass.*var = 42;
cout << myclass.*var << "\n";
}
};
You use it as a regular pointer-to-member:
template< int (MyClass::*var) > struct A
{
void foo()
{
MyClass Blah;
Blah.*var = 3;
}
};
Nothing prevents A from having methods taking MyClass as parameters though:
template <int (MyClass::*var)>
struct A {
int get(MyClass const& mc) const { return mc.*var; }
void set(MyClass& mc, int i) { mc.*var = i; }
};
int main() {
MyClass mc;
A<&MyClass::membervar> a;
a.set(mc, 3);
std::cout << a.get(mc) << "\n"; // prints 3
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I am trying to figure a problem with a piece of code that I wrote.
I have two structs (bar and foo) that can be used to contruct a templated class myClass.
For this example, the structs will contain information about the size of a vector of a templated quantity (called baseType).
There is also a third struct called infoClass which will contain some information about the object, e.g., its name.
The class myClass will inherite from infoClass and from either bar or foo.
When I write the operator+ for myClass, the compiler is allowing me to do:
myClass<double, foo> = myClass<double, bar> + myClass<double, bar>;
I was able to track the problem to the constructor myClass (const infoClass& obj).
If I put an extra parameter I will get the error I am expecting saying:
error: conversion from ‘myClass<[...],bar>’ to non-scalar type ‘myClass<[...],foo>’ requested
However, I am not understanding why do I need to put an extra parameter in the constructor for the code to work as expected.
Can anyone shed some light on this?
I have the following code:
#include <iostream>
#include <vector>
struct bar
{
int size{10};
};
struct foo
{
int size{15};
};
struct infoClass
{
std::string name;
};
template<typename baseType, typename myType>
class myClass;
typedef myClass<double, bar> doubleBar;
typedef myClass<double, foo> doubleFoo;
template<typename baseType, typename myType>
class myClass
:
public infoClass,
public myType
{
private:
std::vector<baseType> data_;
public:
myClass(double initValue) : data_(this->size,{initValue}){}
myClass (const infoClass& obj) // myClass (const infoClass& obj, double someVar) //this works
:
data_(this->size,{0})
{
this->name = obj.name;
}
std::vector<baseType>& data() {return data_;}
const std::vector<baseType>& data() const {return data_;}
};
template<typename baseType, typename myType>
myClass<baseType, myType> operator+(const myClass<baseType, myType>& obj1, const myClass<baseType, myType>& obj2)
{
if(obj1.data().size() != obj2.data().size())
std::cout << "error, sizes are different" << std::endl;
myClass<baseType, myType> result(0);
for(int i=0; i < obj1.data().size(); i++)
{
result.data()[i] = obj1.data()[i] + obj2.data()[i];
}
return result;
}
int main()
{
doubleBar a(3);
doubleBar b(4);
doubleBar c = a + b;
doubleFoo e = a + a;
std::cout << "End" << std::endl;
return 0;
}
You problem is indeed in myClass (const infoClass& obj) constructor. Such constructor is called "converting construcor" and can be used by compiler to implicitly convert one type to another.
Since both of you types doubleBar and doubleFoo can be implicitly converted to infoClass comlpiler then can convert it back to either of these classes. To prevent this implicit behavior just add keyword explicit in this constructor declaration, i.e.:
explicit myClass (const infoClass& obj)
This will tell compiler not to use this constructor for implicit conversion and everything will work as you expect.
I found this post when i try to understand what xvalue, glvalue and prvalue values are.
I also intuitively think that, under the hood, this is passed to member function like :
void SomeClass::func(SomeClass* this, int a, int b)
but as stated in the answer and the standard, this should be prvalue so my assumption was wrong.
I tried to mimic this as prvalue
template<typename T>
T* possible_this_impl() {
T* ref { nullptr };
// Somehow retrieve the currently referred object
return ref;
}
struct foo {
int a_non_static_member_function() {
possible_this_impl<foo>(); // Now it is a prvalue
possible_this_impl<foo>()->x;
possible_this_impl<foo>()->y;
}
public:
int x {};
int y {};
};
int main()
{
foo f;
f.a_non_static_member_function();
}
But actually, I wonder what could be possible implementation of this ? Could anyone enlighten me ?
Note: No need very deep explanation but maybe a simple explanation could be enough.
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 3 years ago.
Improve this question
I am curious what exactly you pass in when using a class object as a parameter with array brackets after. The format i am talking about is
class Class {};
//This is just an example
void Function( int x, int y, Class object[] ) {
double stuff = object[x].getThing();
double stuffed = object[y].getThing();
}
A function parameter having an array type is implicitly adjusted by the compiler to pointer to the array element type.
So for example these function declarations
void f( T a[] );
void f( T a[1] );
void f( T a[100] );
where T is some arbitrary type as for example
class Class
{
//…
};
declare the same one function that is equivalent to the declaration
void f( T *a );
You may include all these declarations in one compilation unit though the compiler can issue a warning that these declarations are redundant.
On the other hand, an array passed to such a function is in turn implicitly converted to pointer to its first element.
Of course you can even pass to such a function a pointer to a single object instead of specifying an array as an argument because in any case the function deals with a pointer.
Here is a demonstrative program.
#include <iostream>
class Class
{
public:
int x = 10;
};
void f( Class object[] );
// The definition of the above function
void f( Class *object )
{
std::cout << object[0].x << '\n';
}
int main()
{
Class object;
Class objects[10];
f( &object );
f( objects );
return 0;
}
Its output is
10
10
This question already has answers here:
How to call through a member function pointer?
(2 answers)
Closed 4 years ago.
I try to give a reference to a member function (func) to a function (Multiprotocol) and call it with an object (z) of this class.
But i have problems with the line
result = z.*f(std::forward<Args>(args)...));
I tried things like
z.(*f) (std::forward<Args>(args)...))
and
z.(*(&f)(std::forward<Args>(args)...));
But i don't knwow how to this. Can anybody help me?
class test
{
public:
static int func()
{
std::cout << "in func";
}
};
class MultiProtocol
{
public:
template<typename Function, typename... Args>
bool functionImpl(Function f, Args&&... args)
{
int result = 0;
result = z.*f(std::forward<Args>(args)...));
return result;
}
private:
test z;
};
Main is:
int main()
{
MultiProtocol rr;
rr.functionImpl(&test::func);
}
Nearly, it is:
(z.*f)(std::forward<Args>(args)...)
Cannot be
z.(*f) (std::forward<Args>(args)...))
z.(*(&f)(std::forward<Args>(args)...));
as we should use operator .* (or ->*).
z.*f(std::forward<Args>(args)...) would be valid if f(args...) would return int test::* (pointer on member) as it is actually z .* (f(std::forward<Args>(args)...)).
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 would like to cast a pointer to an instance of MyClass to an int*, preferably in such a way that I can do this:
void function(int*) {...};
MyClass * instance = new MyClass;
function(instance);
The int pointer should NOT be a binary copy of the MyClass pointer. Currently, I am using the following code to acheive a similar result:
int * MyClass::getIntPointer() {return &my_int;}
How do I cast a MyClass* to an int*?
Are you trying to access an int member of your class? If so, you can do this:
class MyClass {
public:
int myInt;
};
void function(int*) {...};
MyClass* instance = new MyClass;
function(&instance->myInt);
You don't want to cast MyClass to an int, you just want to access the member of MyClass.
So here's what that line means:
instance-> // follow the pointer to the actual MyClass object.
instance->myInt // access the int, "myInt"
&instance->myInt // get the address of that int
function(&instance->myInt); // call "function", passing to it the address of "myInt"
EDIT:
If you're creating a class that wraps an int, you can do this with a custom casting operator, as #cmbasnett suggests:
class MyClass {
public:
int* operator int*() { return &my_int; }
private:
int my_int;
};
MyClass instance;
function(instance); // this line will trigger the custom cast operator.
Maybe either of these strike your fancy:
#include <iostream>
struct MyClass
{
int myInt;
operator int*()
{
return &myInt;
}
};
int main()
{
MyClass* instance = new MyClass();
//method 1
instance->myInt = 42;
int* a = &(instance->myInt);
//method 2
int* b = *instance;
std::cout << *a << std::endl;
std::cout << *b << std::endl;
}
Sorry, you're stuck. You cannot overload the typecast operator for a pointer type. This is the only way you could cast from MyClass* directly to int* and require the resulting int* to point at the first int member, even if the class' storage is non-POD.
If you could guarantee that MyClass was always a POD type, then reinterpret_cast<int*>(instance) would be sufficient. But your demand that "The int pointer should NOT be a binary copy of the MyClass pointer" implies that there is no such guarantee.
If you were willing to start with a MyClass& instead of a MyClass*, then you could use cmbasnett's example of adding a typecast overload to the class.