How to check if a member name (variable or function) exists in a class, with or without specifying type?
C++03
#define HasMember(NAME) \
template<class Class, typename Type = void> \
struct HasMember_##NAME \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(static_cast<Type>(&V::NAME))>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}; \
template<class Class> \
struct HasMember_##NAME<Class, void> \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(&V::NAME)>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}
Usage: Simply invoke the macro with whatever member you want to find:
HasMember(Foo); // Creates a SFINAE `class HasMember_Foo`
HasMember(i); // Creates a SFINAE `class HasMember_i`
Now we can utilize HasMember_X
to check X
in ANY class
as below:
#include<iostream>
struct S
{
void Foo () const {}
// void Foo () {} // If uncommented then type should be mentioned in `HasMember_Foo`
int i;
};
int main ()
{
std::cout << HasMember_Foo<S, void (S::*) () const>::value << "\n";
std::cout << HasMember_Foo<S>::value << "\n";
std::cout << HasMember_i<S, int (S::*)>::value << "\n";
std::cout << HasMember_i<S>::value << "\n";
}
Catches:
- In case of methods, if we don't mention the type then the
class
must not have overloaded methods. If it has then this trick fails.
i.e. even though the named member is present more than once, the result will befalse
. - If the member is part of base class, then this trick fails; e.g. if
B
is base ofS
&void B::Bar ()
is present, thenHasMember_Bar<S, void (B::*)()>::value
orHasMember_Bar<S, void (S::*)()>::value
orHasMember_Bar<S>::value
will givefalse
Test if a not class member function exists (SFINAE)
You may use something like this:
template <class T>
static auto hasPrintMethod(int)
->std::integral_constant<bool, std::is_class<decltype(print(T()))>::value>;
template <class>
static auto hasPrintMethod(...)->std::false_type;
template <typename T>
struct HasPrintMethod : decltype(hasPrintMethod<T>(0)) {
};
Here the decltype(print(T()))
is std::string
for classes for which your non-member function is defined, and an erroneous type for other classes. So, according to SFINAE concept, HasPrintMethod<A>::value
is equal to true
for class A
with print
function defined and is equal to false
otherwise.
Templated check for the existence of a class member function?
Yes, with SFINAE you can check if a given class does provide a certain method. Here's the working code:
#include <iostream>
struct Hello
{
int helloworld() { return 0; }
};
struct Generic {};
// SFINAE test
template <typename T>
class has_helloworld
{
typedef char one;
struct two { char x[2]; };
template <typename C> static one test( decltype(&C::helloworld) ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
int main(int argc, char *argv[])
{
std::cout << has_helloworld<Hello>::value << std::endl;
std::cout << has_helloworld<Generic>::value << std::endl;
return 0;
}
I've just tested it with Linux and gcc 4.1/4.3. I don't know if it's portable to other platforms running different compilers.
How to detect whether there is a specific member variable in class?
Another way is this one, which relies on SFINAE for expressions too. If the name lookup results in ambiguity, the compiler will reject the template
template<typename T> struct HasX {
struct Fallback { int x; }; // introduce member name "x"
struct Derived : T, Fallback { };
template<typename C, C> struct ChT;
template<typename C> static char (&f(ChT<int Fallback::*, &C::x>*))[1];
template<typename C> static char (&f(...))[2];
static bool const value = sizeof(f<Derived>(0)) == 2;
};
struct A { int x; };
struct B { int X; };
int main() {
std::cout << HasX<A>::value << std::endl; // 1
std::cout << HasX<B>::value << std::endl; // 0
}
It's based on a brilliant idea of someone on usenet.
Note: HasX checks for any data or function member called x, with arbitrary type. The sole purpose of introducing the member name is to have a possible ambiguity for member-name lookup - the type of the member isn't important.
How to check if a function exists in C/C++?
While other replies are helpful advices (dlsym
, function pointers, ...), you cannot compile C++ code referring to a function which does not exist. At minimum, the function has to be declared; if it is not, your code won't compile. If nothing (a compilation unit, some object file, some library) defines the function, the linker would complain (unless it is weak, see below).
But you should really explain why you are asking that. I can't guess, and there is some way to achieve your unstated goal.
Notice that dlsym
often requires functions without name mangling, i.e. declared as extern "C"
.
If coding on Linux with GCC, you might also use the weak
function attribute in declarations. The linker would then set undefined weak symbols to null.
addenda
If you are getting the function name from some input, you should be aware that only a subset of functions should be callable that way (if you call an arbitrary function without care, it will crash!) and you'll better explicitly construct that subset. You could then use a std::map
, or dlsym
(with each function in the subset declared extern "C"
). Notice that dlopen
with a NULL
path gives a handle to the main program, which you should link with -rdynamic
to have it work correctly.
You really want to call by their name only a suitably defined subset of functions. For instance, you probably don't want to call this way abort
, exit
, or fork
.
NB. If you know dynamically the signature of the called function, you might want to use libffi to call it.
Check if a class has a member function of a given signature
I'm not sure if I understand you correctly, but you may exploit SFINAE to detect function presence at compile-time. Example from my code (tests if class has member function size_t used_memory() const).
template<typename T>
struct HasUsedMemoryMethod
{
template<typename U, size_t (U::*)() const> struct SFINAE {};
template<typename U> static char Test(SFINAE<U, &U::used_memory>*);
template<typename U> static int Test(...);
static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};
template<typename TMap>
void ReportMemUsage(const TMap& m, std::true_type)
{
// We may call used_memory() on m here.
}
template<typename TMap>
void ReportMemUsage(const TMap&, std::false_type)
{
}
template<typename TMap>
void ReportMemUsage(const TMap& m)
{
ReportMemUsage(m,
std::integral_constant<bool, HasUsedMemoryMethod<TMap>::Has>());
}
Python check if function exists without running it
You can use dir
to check if a name is in a module:
>>> import os
>>> "walk" in dir(os)
True
>>>
In the sample code above, we test for the os.walk
function.
How to check if function exists in JavaScript?
Try something like this:
if (typeof me.onChange !== "undefined") {
// safe to use the function
}
or better yet (as per UpTheCreek upvoted comment)
if (typeof me.onChange === "function") {
// safe to use the function
}
Type trait: Check if class have specific function (maybe inherit)
Here is one old school C++03 way of doing it. Typically it can be used as a utility and get it molded for any method or variable.
#define HasMember(NAME) \
template<class Class, typename Type = void> \
struct HasMember_##NAME \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(static_cast<Type>(&V::NAME))>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}; \
template<class Class> \
struct HasMember_##NAME<Class, void> \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(&V::NAME)>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}
Instantiate:
HasMember(Foo);
Usage:
HasMember_Foo<B>::value // without type (but then no overload allowed)
HasMember_Foo<C, int (C::*)(float)>::value // needs type
Note that, here I am providing two HasMember_Foo
s, 1 with type and 1 without type. They are generalized for any type (not just specific to int (X::*)(float)
). If there is no type mentioned, then the class must have only 1 such method (without overload). Hence, it's always safer to mention the type; As you have done in your question, the specific type is int (X::*)(float)
. BTW, this also can be included using another macro.
Without such extra macro, in case of class C
and class D
, you may have to specify the type of the method.
Here is a demo with your code.
Here it's assumed that whichever class member (function or variable) is chosen, must be public
scoped. i.e. If X::foo
is private
then this solution will not work.
Check if a variable is of function type
Sure underscore's way is more efficient, but the best way to check, when efficiency isn't an issue, is written on underscore's page linked by @Paul Rosania.
Inspired by underscore, the final isFunction function is as follows:
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}
Note: This solution doesn't work for async functions, generators or proxied functions. Please see other answers for more up to date solutions.
Related Topics
Strange "Unsigned Long Long Int" Behaviour
How to Read Frames from Videocapture from Secondary Webcam with Opencv
Initializing a Ublas Vector from a C Array
C++ System() Function - How to Collect the Output of the Issued Command
Removing '#Include <Algorithm>' Doesn't Break the Code
How to Speed Up This Histogram of Lut Lookups
What Is Aggregate Initialization
Apply Function to All Eigen Matrix Element
Why Must Initializer List Order Match Member Declaration Order
When a Float Variable Goes Out of the Float Limits, What Happens
When to Use C++ Private Inheritance Over Composition
When How to Omit the Return Type in a C++11 Lambda
C++ Type of Enclosing Class in Static Member Function
Visual Studio Code C++11 Extension Warning
Is There a Clean Way to Prevent Windows.H from Creating a Near & Far MACro
Brace Initialization for Inherited Pod