below given code compiles successfuly:
template <typename T, T nontype_param>
class C;
class X {
public:
int n;
};
int main()
{
C<int X::*, &X::n>* c; //Here
return 1;
}
How the Scope resolution operator works here rather than the . operator? Are we allowed to access a non static member like this?
reference: C++ Templates The Complete Guide , Section 8.3.3 Nontype Arguments
Yes, this code is valid, and the source of your confusion isn't actually related to templates.
int X::* is a pointer-to-member (specifically a pointer to int data member on type X). The pointer itself does not convey an instance of the object, so you can indeed take a pointer to a non-static member. (In fact, a pointer to a static member would just be a regular pointer, not a pointer-to-member!)
You supply the object instance at the time you use the pointer, not at the time you take the pointer.
// Declare a pointer to a data member of type int on object of type X, and
// initialize it to point to the X::n member.
int X::*ptr = &X::n;
// *ptr is not valid on member pointers. Rather, we need to supply an instance:
X instance;
// Then use the member pointer dereference operator .*
(instance.*ptr) = 5; // Same as "instance.n = 5;" in this case.
Related
I have defined a deleter for set having pointer object , but when I have defined in the below manner it wasn't working and saying
In function 'int main()': 41:43: error: missing template arguments before '(' token In file included from /usr/include/c++/4.9/set:
That was the line where I was using Deleter
template <typename T>
struct Deleter
{
void operator () (T *ptr)
{
delete ptr;
}
};
But when I changed the place of template declaration as shown below it started working .
struct Deleter1
{
template <typename T>
void operator () (T *ptr)
{
delete ptr;
}
};
Can anybody explains what exactly the difference is . Because when we declare a class having template variable or even function having template parameter we declare template declaration before the class definition .
When you use a function template the compiler can often tell from the way the function is called what the template argument must be. So in a call like this
Deleter1 d1;
int *ip = new int;
d1(ip);
the compiler infers that T is int.
For the corresponding code using the first one, you'd write
Deleter d;
int *ip = new int;
d(ip);
note that at the point of definition of d there is no way for the compiler to know that d() will be called with an int*.
With your first type, Deleter, you create objects which accept a fixed type.
// del_int only accepts int pointers
Deleter<int> del_int;
// del_string only accepts std::string pointers
Deleter<std::string> del_string;
int* ip = new int;
std::string* sp = new std::string;
del_int(ip); // ok
del_string(sp); // ok
del_int(sp); // error
del_string(ip) // error
But with Deleter1, you can create a single object, and it will accept any pointer, because its member operator() is templated.
// del_any will accept any kind of pointer
Deleter1 del_any;
int* ip = new int;
std::string* sp = new std::string;
del_any(ip); // ok
del_any(sp); // ok
Can anybody explains what exactly the difference is
The first is a class template. The instances of the template are classes that have a member function.
int* silly_int = new int;
float* silly_float = new float;
Deleter<int> d; // Deleter<int> is a class
d(silly_int); // it can delete int pointers using the member function
Deleter<float> d2; // Deleter<float> is another class
d2(silly_float); // it can delete float pointers
The second is a class that has a member function template. The instances of the template are member functions.
Deleter1 d3; // Deleter1 is a class
d3(silly_int); // it too can delete int pointers
d3(silly_float); // and pointers of other types as well
// using different instance of the member function template
The first has the template parameter on the struct and to create the struct the compiler needs to know what type it is creating the struct for. As we're using the default constructor which has no arguments the compiler cant deduce the type and you need to explicitly specify it, i.e.
Deleter<Foo>()
The compiler then creates a 'Foo Deleter' struct with an operator() function that only accepts an argument of type Foo*.
The second version defines a regular struct that has a templated function.
In this case the compiler will generate an operator() function for every type that the function is called with. It will deduce the type from the function argument.
Win7
cygwin gcc (GCC) 4.8.2 64-bits (2000 C++)
I'm trying to construct a typedef to a member function:
class MyClass {
typedef int32_t (*func1)(class const * const name);
typedef int32_t (func2)(class const * const name);
public:
int32_t memberFunc(class const * const name);
}
MyClass:: someFunc() {
func1 x, y;
x = &memberFunc; // error: address of non-static member illegal
y = memberFunc; // error: conversion error
func2 z;
z = memberFunc; // error: invalid use of member function
}
I've looked at previous posts and they indicate that the func1 definition is correct and that the assignment (x = &memberFunc) is also correct - at least for non-member functions. I would prefer not making memberFunc static if I can. So, any good examples and any good explanations?
thanks
art
In fact, a member function receives one more parameter: this pointer. So normal function-pointer and member function-pointer is different. member function-poineter syntax is like the following:
typedef int32_t (MyClass::*func1)(MyClass const * const name);
and It is used as follows:
func1 f = &MyClass::memberFunc;
MyClass c;
MyClass *pc = &c;
(c.*f)(nullptr);
(pc->*f)(nullptr);
PS. class const * const name <-- you've mistyped? I think not class, but MyClass
edit: You can use std::bind as follows:
MyClass c;
auto f = std::bind(&MyClass::memberFunc, &c /*this pointer*/);
In this, f is NOT member function-pointer, but binder function-object.
Function pointers cannot bind to member functions.
You need a pointer-to-member-function, or something easier to use like std::function and a call to std::bind.
You need what is known as a closure for this to work.
Effectively, the address of your function is insufficient to call a non-static class function, because instantiated objects have non-local storage. Thus, to actually call a member function, you need a this pointer as well.
It has been explained elsewhere, but I figured I would throw in the technical term. Anything that wraps the function address and the necessary parameters (namely a this pointer) to satisfy the calling convention for a class function is an implementation of a closure.
I am new to function pointers and I would like your help.
I am having a method:
int test3(int i)
{
return i;
}
Then in another method(not main) I do:
int (*pTest3)(int) = test3;
From the examples that I have read this seems ok.
However, I get a compile time error:
testFile.cpp:277:25: error: argument of type ‘int
({anonymous}::CheckingConsumer::)(int)’ does not match ‘int (*)(int)’
I do not understand what is wrong. Any help would be appreciated.
Thanks a lot.
Your test3 is a member function of a struct or a class. Class member functions have a hidden this parameter passed into them and so cannot be used with plain function pointers. You need to either declare the function as static or move it outside the struct/class, so that it no longer has a hidden this parameter, or use a class method pointer instead of a function pointer:
// static class method:
class X
{
static int test3(int i)
{
...
}
};
// Non-class method, at global scope
int test3(int i)
{
...
}
// Class method pointer
class X
{
int test3(int i)
{
...
}
};
// Create the method pointer
int (X::*pTest3) = &X::test3;
X *obj;
// Call the method pointer on an object
(obj ->* pTest3)(42);
Your method test3 seems to be an instance method. Later on you define pTest3 as function pointer, not as member function pointer.
Main difference between simple pointers and member pointers is that using the member pointer requires an instance of the object. An instance of the object tells what object should be processed and the value of the pointer tells what data field of the object should be used or what member function should be called. Value of the member pointer is conceptually equivalent to the offset from the beginning of the object to its member.
Declaring the member pointer using typedef:
typedef int (SomeClass::*MyMethodPtr)(int i);
MyMethodPtr ptr3 = SomeClass::test3;
Now using this pointer:
class SomeClass *pab = &ab;
int ret_value = (pab->*ptr3)(4);
Note that the instance of the class is used. There is other important point about the member pointers. They are implemented as structs that contain inside from 2 to 5 simple pointers and offsets depending on the compiler and other aspects like multiple inheritance, presence of vitrual base classes, etc.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have some questions about C++ from a C# developer.
For a few days I have been looking at some C++ code, and I have the following questions:
When do use Foo::, Foo. and Foo-> ?
When do I use a real constructor and when just String a; (sometimes I need to do something like String a("foo");)
What is the difference between these signatures: int foo(int a) and int foo(int &a)?
:: is used either to explicitly specify a namespace (std::string, for example, for the string class in the namespace std), or for static members of a class.
. is used much as in C#, to refer to a member of a class.
-> is used with pointers. If p is a pointer to an object obj, then p->x has the same meaning as obj.x.
when do i use a real constructor and when just String a; (sometimes i need to do something like String a("foo");)
When you need to. String a is roughly equivalent to C#'s a = new String() (with the caveat that if String is a non-POD type, it may contain uninitialized members.)
If you need a initialized to a specific value, you do that. (either with String a("foo"), or with String a = "foo")
where is the difference between these signatures: int foo(int a) and int foo(int &a)?
The & denotes a reference. It's not quite a C# reference, but there are similarities. In C#, you have value types and reference types, and reference types are always passed by reference.
In C++, there's no such distinction. Every type can be passed by value or by reference. The type T& is a reference to T. In other words, given the following code:
void foo(int& j);
void bar(int j);
int i = 42;
foo(i);
bar(i);
foo will get a reference to i, which means it it can modify the value of i.
bar will get a copy of i, which means that any modifications it makes will not be reflected in i.
You often use const T& (a reference to const T) as a way to avoid the copy, while still preventing the callee from modifying the object.
1: Assuming you which to call a method
Foo::theMethod(...)
is for example used when calling a static method of a class Foo
Foo.theMethod(...)
is when you have an object named Foo
Foo->theMethod(...)
is when you have a pointer to a object of named Foo
2:
String a;
calls the default constructor that takes no arguments
String a("foo")
calls a overloaded constructor
3:
int foo(int &a)
takes a reference to an integer, so within the method you are able to manipulate a.
int foo(int a)
makes a copy, manipulating it wont have any effect of the actual parameter passed in after leaving the method.
Question 1:
It depends on what Foo is. The :: operator is called the scope
resolution operator; the operand on the right must be a namespace or a
class, and the operand to the left a member of the namespace or class.
If Foo is a class, Foo:: can be used to access a static member, or
from within a member of a derived class, to access the member of the
base class: e.g.:
class Foo
{
public:
virtual void f();
static void g();
};
int h()
{
Foo::g();
}
class Derived : public Foo
{
public:
virtual void f()
{
Foo::f(); // Call function in base class...
}
}
It's often used to access namespace members as well, e.g. std::cout
(the cout object in namespace std).
The . operator is a member access operator, and requires an object (or
a reference to an object) as the left hand operand. Thus (using the
above definitions):
Foo obj;
obj.f();
void i( Foo& rFoo )
{
rFoo.f();
}
It can also be used to access static members, if you have an instance:
Foo obj;
obj.g();
The -> is very much like the . operator, except that it takes a
pointer to an instance, rather than an instance, and (very importantly)
it can be overloaded. Thus:
Foo* obj;
obj->g();
// And if Ptr is a user defined type with an overloaded
// `operator->` which returns a Foo*
Ptr obj;
obj->g();
Again, you can also use this syntax to access a static member, if you
have a pointer to an object.
Question 2:
The definition String a; calls a real constructor. You use String
a; when you want the default constructor; the one with no parameters.
You use String a( "foo" ); when you want the constructor which takes a
char const* (or a char const (&)[4], but that's highly unlikely, since it
will only work for a string literal with exactly three characters).
In general, when defining variables:
String a; // default constructor...
String a1(); // NOT what it looks like: this is a
// function declaration, and not the
// definition of a variable!!!
String b( x, y, z ); // constructor taking x, y and z as arguments...
String c = x; // implicitly convert `x` to String, then
// copy constructor.
The last form is a bit tricky, since the copy constructor may be (and
almost always is) elided, but the legality of the program is defined by
the rule above: there must be a way of implicitly converting x into a
String, and String must have an accessible copy constructor.
In other contexts, e.g. new String(), the form with empty parameters
can be used for "value construction", which is the default constructor
if there is a user defined one, otherwise zero initialization.
Question 3:
The first is pass by value, and passes a copy of the argument to the
function. The second is pass by reference, and passes a reference
(which behaves sort of like a hidden, automatically dereferenced
pointer) to the function. Thus:
void f( int a )
{
++ a; // Modifies local copy, has no effect on the argument.
}
void g( int& a )
{
++ a; // Modifies the variable passed as an argument.
}
Note that in the first case, you can pass an arbitrary expression; in
the second, you must pass something called an lvalue—that is,
something you can access afterwards using a similar expression (a named
variable, or a dererenced pointer, or an element in a named array,
etc.).
String a : construct an empty String object
String a("foo") : construct a String object initalized to "foo"
int foo(int a) : pass a by value/copy to foo. Inside foo if you modify a , a will not be impacted outside foo
int foo(int& a) : pass a by reference inside foo. If you modify a , a will also be modify once foo ended
Foo:: - Static methods
Foo. - Instance Methods when you have a stack object instance. (MyObject obj)
Foo-> - Instance methods when you have a object pointer. (MyObject* pObj = new MyObject())
Whenever you need to pass some value to the constructor.
int& is a reference to an int. Any changes to a within the method will affect a outside the method. (Equivalent to ref in C#)
I have a class :
class X{
public :
void f ( int ) ;
int a ;
} ;
And the task is "Inside the code provide declarations for :
pointer to int variable of class X
pointer to function void(int) defined inside class X
pointer to double variable of class X"
Ok so pointer to int a will be just int *x = &a, right ? If there is no double in X can I already create pointer to double inside this class ? And the biggest problem is the second task. How one declares pointer to function ?
These are called pointers to members. They are not regular pointers, i.e. not addresses, but "sort-of" offsets into an instance of the class (it gets a bit tricky with virtual functions.) So:
int X::*ptr_to_int_member;
void (X::*ptr_to_member_func)( int );
double X::*ptr_to_double_member;
You need to declare them as pointer-to-members. Pointers to members are different than usual pointers in that they are the address of a member of a structure or class, not an absolute address like regular pointers.
For more information, read this.
A pointer to any type is declared with an '*' after the type name and the variable name:
Franks_Class * p_franks_class; // Declares a pointer to an instance of Franks_Class.
The more obscure declaration is for the function:
typedef void (*My_Int_Function_Ptr)(int parameter);
which declares a type (synonym), named My_Int_Function_Ptr, a pointer to a function taking an int parameter and returning void.
From this and a good C++ book, you should be able to answer the rest of your questions.