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...
Related
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…
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__; }
I want to reimplement a library of which I have the header file.
I would prefer not to change the .h file since that would require changes in the programs that use the library (plus some legal reasons).
EDIT: I also cannot change the code that uses the library and instantiates class X!
the lib.h defines a class X (simplified version):
class X
{
public:
bool Function(BOOL q, INT p);
BOOL a;
INT b;
};
(BOOL and INT are just some datatypes used by the library, these classes wrap a primitive data type of bool and int).
I implemented this class in my_lib_implementation.cpp:
bool X::Function(BOOL q, INT p)
{
return true;
}
The .h file does not define a constructor, so this means that there is an implicit constructor (right?).
Problem is, I need to initialise the variables a and b for my implementation of Function(BOOL q, INT p) to work correctly.
However if I add the following, I get compile errors ("error: definition of implicitly-declared 'X::X()'", gcc 4.4):
X::X()
{
a=true;
b=0;
}
Is it possible to overload the constructor through some magic that I do not know about? Are there other options for initializing the variables?
There is a an implementation of the library (that I can't use), so it seems like it should be possible somehow?
I only just started programming C++ this week (I do have extensive experience with other languages), so this problem is probably just my lack of basic knowledge.
Hope you guys can help me out!
No, it's not possible, the compiler-generated default constructor cannot be overloaded.
You can however initialize the members with the following syntax:
X x = {true, 0};
There isn't really a way to directly do what you're asking. (Provide a default constructor without declaring it in the class.)
The closest you can come to this is to also redefine the BOOL and INT classes, assuming those have defined default constructors. If they have, then you can change the meaning of the default to whatever you want.
Alternately, you could completely change the behavior of the function. You can add members to the class, including for example something to keep track of whether the function has been called yet, or how many times, etc. Or you could define your own betterthanX member and just forward the function calls to the member, and then copy out the results back into the members of the real X class.
A very dirty hack could be to define a preprocessor macro just before including the library header file that changes X to X_. You can then define your own X that inherits from X_ and defines whatever constructor you like. You should #undef the macro after the #include. Don't blame me if you run into insidious bugs.
void foo(int)
{
}
class X
{
void foo()
{
}
void bar()
{
foo(42);
// error: no matching function for call to 'X::foo(int)'
// note: candidate is:
// note: void X::foo()
// note: candidate expects 0 arguments, 1 provided
}
};
Why is C++ unable to call the free function (which is the only one with the correct signature)?
Because the two identifiers are defined in different scopes, and overload resolution only concerns about functions in the same scope. Once the compiler finds that the class has a foo, it stops climbing up to wider scopes (C++11 §3.4.1/1), so the free function foo is hidden.
You need to use a qualified name to refer to the global foo:
::foo(42);
The logical reason is Consistency.
Suppose as per the suggestion, compiler resolves foo(42) to
::foo(int).
Now after sometime, if you change X::foo() to X::foo(int) then
foo(42) will be resolved to X::foo(int). Which is not consistent.
That is the also the reason why derived class function hides base class function when there are similar names.
Such cases can be resolved in 2 ways;
(1) Give fully qualified name (e.g. ::foo(42))
(2) Use using utility; e.g.
void bar()
{
using ::foo;
foo(42);
}
A name in an inner scope hides names in outer scopes. It doesn't matter if it is a function or something else, or if you are in a class or a namespace.
Only if the name lookup finds several functions with the same name will the overload resolution kick in to try to select the one that is the best match for the call.
Really like your question. Also I could say, use this syntax:
::foo(42);
But I can say that in my opinion it's more elegant and good programming, set namespaces, so you can write something like this:
namespace MyNameSpace
{
void foo(int){}
class X
{
void foo(){}
void bar()
{
MyNameSpace::foo(42);
}
};
};
This is a good thing because Namespaces allow to group classes, objects and functions under a name.
PS: Then this help you to understand the meaning of write ::foo(42); when you haven't any namespace.
I cannot answer the why part of your question -- I do not know what was the rationale behind that in the language spec.
To call the global function in your example, use the :: syntax:
::foo(42);
The reason for this is the fact, that the compiler will look for a matching function name first, ignoring return values and parameters. When inside a class, it will try to look for a matching member there (in fact, it will look through all scopes going "upwards"; local scope(s), function scope, class scope, namespace scope, global scope, etc.).
X::foo is the first matching name. THEN (not before) it will try to pick the right overload (if there are multiple declarations) based on the parameters (which is the reason you can overload the same function with different parameters but not different return values only) and then it will check the return value (if there's any).
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.