To clarify, I'm trying to create a macro which makes taking member function addresses a little easier, so I would hope to input a member function name of the current class (and only the member function name), and the macro will use the type of the variable or the type of the enclosing class to actually access the function.
e.g.
#define GETMEMBERFUNCTIONPOINTER(identifier) /*magic code goes here*/
struct myStruct {
void (myStruct::*functionPointer)();
void myMemberFunc() {
}
myStruct() {
functionPointer = GETMEMBERFUNCTIONPOINTER(myMemberFunc);
}
};
is this possible? The closest I've managed is to have each class inherit a private typedef which can be used in the macro
Disclaimer: Macros are evil. Do not use macros.
That being said, I believe the magic code you're looking for would be
#define GETMEMBERFUNCTIONPOINTER(identifier) (&std::remove_pointer_t<decltype(this)>::identifier)
working example here
I do not believe that anyone should be actually doing this, however. If your design requires member function pointers to be taken so frequently that you find yourself wanting for a macro to do it for you, then I highly recommend to seriously question whatever it is that you're doing before you proceed…
Related
Say there is a macro:
#define X(...) foo(__VA_ARGS__)
foo is defined as:
void foo(int a) {}
template<class T>
void foo(int a, T& t) { std::cout<<a<<t.b; }
I'd like to check if X is called within a class or not. If it is called within a class, then I can call the second version foo(100,*this). Otherwise, I'll call the first version without passing *this.
It isn't possible, strictly speaking, to have a macro recognize whether it's invoked within some class or not. You see, macros are expanded by a preprocessor - not by the C++ compiler proper; and the preprocessor has no clue about C++ - it just works on text files. When the actual compiler gets to recognizing the class, the macros are all gone already.
However, you can use some more macros to sort-of achieve this:
#define IN_CLASS_FOO 1
class foo {
/* ... whatever ... */
}
#undef IN_CLASS_FOO
#define IN_CLASS_FOO 0
with this in place, you can modify your X macro to use IN_CLASS_FOO for controlling its behavior. Note that if you expand some code which refers to a this variable, it will have to be defined even if you're not within a class, so it would still not be possible to just use it.
I strongly discourage you from doing so, however - you would most likely be better served by avoiding macro use altogether. Try replacing the macro with a constexpr function.
The keyword this is available within the body of any non-static member function.
Once I saw a pretty old code in macroses like this:
__if_exists(this) \
{ \
// Do something
} \
Statement __if_exists checks in compile-time if the identifier is available in this scope.
But be careful, it is supported by MSVS only, and in general, it is not good to use such things in the code.
Too little information in the question, so the following could be a match or it might not...
class C
{
void foo(int a)
{
::foo(a, *this);
// ^^ resolves to global scope
bar::foo(a, *this);
// ^^ assuming foo resides in namespace "bar"
}
};
So you now have a member function that will be selected whenever you call e. g. foo(77) within the class context, otherwise, the free foo overload will be selected. The macro gets pointless, just drop it.
If it is OK for you that the template parameter will be resolved to class C only, even if called from within sub classes, you could inherit from C for not having to repeat this code in every sub class. Otherwise, you'll get away with curiously recurring templates...
Besides the global scope, of course.
I have a custom assertion class with a macro to cache a reference to __FILE__:
#define DEFINE_THIS_FILE \
static const char THIS_FILE__[] = __FILE__
For source code, using the macro is no big deal since each source has its own scope. However, templated classes can't use source code, so I'm forced to do all my ASSERT() calls in the declaration/definition given by TemplateClass.h
If I use my macro outside of the class definition e.g. Singleton
DEFINE_THIS_FILE;
namespace NE
{
template<typename T>
class Singleton
{
...
}
}
Then the macro winds up in the same scope of any code that #includes Singleton, and the compiler throws a redefinition error for THIS_FILE__. (Of course, this only happens if the other code also uses the DEFINE_THIS_FILE macro.)
If I put the macro inside the declaration, the compiler won't complain but the linker won't be able to find THIS_FILE__ for any given instance of templated class e.g. Singleton:
namespace NE
{
template<typename T>
class Singleton
{
constexpr DEFINE_THIS_FILE; // constexpr modifier required in this case
...
}
}
I assume the linker error I get,
Undefined symbols for architecture x86_64:
"NE::Singleton<NE::NonTemplateType>::THIS_FILE__"
is caused by the template instances not existing in the same scope as where THIS_FILE__ was first defined, Singleton.h
OT: Is there a way to get all instances of my templated type Singleton to share a scope (global is unacceptable) so that all instances can use this static const macro?
Edit1
Further testing confirms: Using the macro DEFINE_THIS_FILE inside each templated method containing an ASSERT() will compile and run correctly....
In this case, the instances aren't sharing a scope, but have a static const char THIS_FILE__ defined for each method. This works, but I suspect that it uses as much or more ROM than a std::assert (with its its implied allocation of __FILE__).
I'll settle for this until an answer to OT comes about :)
Edit2
Silly me. Instead of using the workaround listed in edit above, I might as well create another macro, UNCACHED_ASSERT(argsToCheck) that directly uses __FILE__ instead of a const static representation.
Multiple ASSERTions per method could still benefit from the caching, though.
Still need an answer to OT, though.
You can place your declaration in unnamed namespace
#define DEFINE_THIS_FILE namespace { static const char THIS_FILE__[] = __FILE__; }
So I was learning about classes and I stumbled upon something I found was quite awkward to me.
class Nebla
{
public:
int test()
{
printout();
return x;
}
void printout()
{
printout2();
}
private:
int x,y;
void printout2()
{
cout<<"Testing my class";
}
};
I found that in a class I can use functions before I declare them (prototype them)
You can see I used printout() , printout2() before decleration.
And I can use variables also before declaring them
You can see I did return x; before declareing x.
Why can I use functions and variables in classes before declaration but outside the class if I do that, I get an error?
Thanks
Good question; I've relied on that feature for years without thinking about it. I looked through several C++ books to find an answer, including Stroustrup's The C++ Programming Language and The Annotated C++ Reference Manual, but none acknowledge or explain the difference. But, I think I can reason through it.
The reason, I believe, that your example works is that the bodies of your test and printout aren't truly where they appear in your file. The code
class MyClass {
void someFun() {
x = 5;
}
int x;
};
...which appears to violate the rule of having to declare variables before you use them, is actually equivalent to:
class MyClass {
void someFun();
int x;
};
void MyClass::someFun() {
x = 5;
}
Once we rewrite it like that, it becomes apparent that the stuff inside your MyClass definition is actually a list of declarations. And those can be in any order. You're not relying on x until after it's been declared. I know this to be true because if you were to rewrite the example like so,
void MyClass::someFun() {
x = 5;
}
class MyClass {
void someFun();
int x;
};
...it would no longer compile! So the class definition comes first (with its complete list of members), and then your methods can use any member without regard for the order in which they're declared in the class.
The last piece of the puzzle is that C++ prohibits declaring any class member outside of the class definition, so once the compiler processes your class definition, it knows the full list of class members. This is stated on p.170 of Stroustrup's The Annotated C++ Reference Manual: "The member list defines the full set of members of the class. No member can be added elsewhere."
Thanks for making me investigate this; I learned something new today. :)
Just to make it clear, this is required by the C++ Standard, not just the way several compilers handle class definitions.
N3242 3.3.7:
The potential scope of a name declared in a class consists not only of the declarative region following the name's point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).
The reason you are able to do this is because by the time you call test, printout or printout2, they will have already been created. If you call the function outside the arbitrary function before it's implementation, then you'll get an error.
Think of class member-functions as being asynchronous with the flow of evaluation of the rest of the class. This won't work with stand alone functions, but you can access data members that haven't been instantiated yet. I'm not completely sure why we are able to do this, but I think it has to do with instantitation of the class object.
Besides Philip's good response, Stroustrup gives a nice explanation of Name Lookup Rules in The Design and Evolution of C++. This is described in "6.3 Clarifications". In 6.3.1.1, "The ARM Name Lookup Rules", he mentions 2 rules defined in the ARM:
[1]The type redefinition rule:A type name may not be redefined in a class after it has been used there.
[2] The rewrite rule: Member functions defined inline are analyzed as if they were defined immediately after the end of their class declarations.
So in your case it would apply the rewrite rule (as Philip deduced), that's why you can forward reference those class members.
This book may be mainly of historical interest (it's written in '94), but I think those rules are applied the same way today.
Why can I use functions and variables in classes before declaration
This is because the body of a member function is a complete-class context of a class, as mentioned in the quoted statements below:
From class.mem.general#6:
6. A complete-class context of a class is a:
function body ([dcl.fct.def.general]),
default argument,
noexcept-specifier ([except.spec]), or
default member initializer
within the member-specification of the class.
This means that the usage of printout inside member function test and the usage of printout2 inside member function printout is allowed here even though those members appear later when writing the class definition.
I have a few questions about the static keyword in C++ (and probably with other languages as well.) What is the purpose of declaring a function as static?
void static foo(int aNumber) {
... }
How about a static inline function?
void static inline foo(int aNumber) {
... }
Is there any benefit to using the static keyword with a function, and do those benefits apply to class functions as well?
I realize some datatypes like structs and arrays have to be static when compiling with an older compiler, but is there any point when using a new ANSI-C++ compiler (like MS VC++ 2008)? I know that using a static variable inside a loop saves time by keeping the data in memory and not reallocating memory every loop iteration, but how about when a variable is declared only once, like at the top of a header file or within a namespace?
Depends on Context:
Like many things in C++, static means different things depending on its context.
It's very common in C++ for the same word to mean different things depending on its context.
For example:
* is used for multiplication, dereferencing a pointer, and creating pointers.
& is used to get the address of variables, to declare a reference, and as a bitwise AND operator.
Global use of static:
If you declare a function or variable as static outside of a class and in global scope, it is specific to only that file. If you try to use that variable or function in a different file (via a forward declaration) you will get a linking error.
Example:
a.cpp:
static void fn()
{
cout<<"hello a!"<<endl;
}
b.cpp:
void fn();
void gn()
{
fn();//causes linking error
}
This feature allows you to use a function that no other file will ever see, that way you don't cause possible linker errors of a symbol defined multiple times. The preferred method to do this is with anonymous namespaces though:
a.cpp:
namespace
{
void fn() // will be static to a.cpp
{
cout<<"hello a!"<<endl;
}
}
Inside of a class use of static:
If you declare a function or variable as static inside of a class (or struct), it is a class function or class variable. This means that there is only one for that whole class. A class function can only use class variables. A class variable is shared amongst all instances of that class.
class C
{
public:
static void fn()
{
y = 4;//<--- compiling error
// can't access member variable within a static function.
}
int y;
}
This is a great feature to use if you have something that is specific to the class of your objects, but not specific to an instance.
Inside a function use of static:
If you declare a variable as static inside of a function, you can consider that the variable value will persist upon calls. It will only be initialized once.
Example:
//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
static int x = 0;
cout << x << endl;
x++;
}
I personally try to avoid this, and you probably should to. It is not good to have global state. It is better to have functions that given the same input guarantees the same output.
Just like in the English language:
The concept of context sensitive meaning is not specific to C++, you can even see it in the English language.
I am going to screen a movie (Means showing the movie)
The screen on the TV is broken (Means a part of the TV)
Other meanings in other programming languages:
Depending on the programming language there can be a different meaning, but the first thing most people think of when you say static is a class variable/function vs a member variable/function.
I hang around on the ##c++ irc channel on irc.freenode.net and I really like the clarification on static that the bot nolyc is programmed to give. I quote word for word:
When used inside a function, the
static keyword indicates that a
variable is shared between all calls
of the function. When used inside a
class, it indicates that the variable
or function is a member but is not
tied to a specific instance. When
used inside a namespace, it specifies
internal linkage.
I hope that clears things up. I haven't answered all your questions. I would say that you should use the static keyword to do what it was intended to do. Use it as a tool to accompolish your task, if it is the right one for the job. As far as benefits go, I wouldn't worry. If you need to optimize, then think about those effects if there is no other resort.
I hope this helps.
Is there any way, in C++, to define nested macros/constants within a class, in a similiar fashion to nested typedefs, or a method to acheive similiar functionality? The motive is generally for the macros to be used by templates.
class SomeClass
{
public:
#define SomeConstant 123
};
int x=SomeClass::SomeConstant;
Ofcourse, static const members can do the job, but those are physical variables, while I'm looking for a simple macro-like behavior.
You can't do what you want with macros. Macros have no concept of scoping.
But for simple int values you can do what you want with enums.
class SomeClass
{
public:
enum {
SomeConstant=123
};
};
int x=SomeClass::SomeConstant;
A fully scoped name for the value, but no space taken for it, even in debug builds - you couldn't take its address if you wanted to.
Const values declared and defined in-place are exactly what you need here: the compiler can and will optimise them away completely so they end up being exactly the same as using the #define in the first place, but with the benefits of strict scoping.
class SomeClass {
public:
static const int someValue = 10;
};
This doesn't take up any extra space - no memory is allocated to store "someValue". You can prove this: if you try and use the "someValue" as a real object (ie you try and get its address), then the linker will tell you it's undefined.
Macros completely ignore scope - they are expanded before the C++ compilation. You just can't do that.
Use of static const often leads to no variable being allocated - the compiler treats it as a constant.
Macro pre-processors generally don't have any idea of language context; thus they don't know what a "class" is making "nesting inside a class" not make sense in the first place.
For what you want, either use static const, or use the full name (assuming the preprocessor allows colons in macro names, not 100% sure on that) - though it won't allow you to inherit the constant on derived classes:
#define SomeClass::SomeConstant 123
You can do this with templates:
template < int someConstant = 123 > class SomeClass
{
public:
void outputConstant() { cout << "We think the answer is:" << someConstant; }
}
But that isn't precisely what you want because you have to declare an instance of the class as:
int main(int argc, char *argv)
{
SomeClass<123> myInstance;
}
I know others have explained the bit about macros, but allow me to add: #define is processed by the pre-processor, not the compiler. In the standard is a section called "translation phases" which explains this in more detail, but for your question the point is that macros are evaluated before the class is even compiled, and the scope at which the #define occurs is not known.
The authoritative book on this subject (programming with templates during the compile stage) is Modern C++ Design: Generic Programming and Design Patterns Applied, by Andrei Alexandrescu.
I don't understand your objection to using a static const.
It will not effect the size of your class, and the compiler will optimise to achieve what you think you'd get from a macro.
"Static members are physical variables".
What's against this? The only reason to object to this would be memory usage. But since the member is static, the memory would only be occupied once with the intended content.
On the contrary, with a macro, the contend would be present at every single usage location in the binary.
EDIT:
In case the variable is of an integral type, smaller than a pointer, it's probably best to define the constant in the class declaration. Optimizing compilers can then inline the value in the calling code, just like for a macro.