How to detect whether there is a specific member variable in class?

For creating algorithm template function I need to know whether x or X (and y or Y) in class that is template argument. It may by useful when using my function for MFC CPoint class or GDI+ PointF class or some others. All of them use different x in them. My solution could be reduces to the following code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }
struct P1 {int x; };
struct P2 {float X; };
// it also could be struct P3 {unknown_type X; };
int main()
{
P1 p1 = {1};
P2 p2 = {1};
Check_x(p1); // must return true
Check_x(p2); // must return false
return 0;
}
</code>
<code> template<int> struct TT {typedef int type;}; template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; } struct P1 {int x; }; struct P2 {float X; }; // it also could be struct P3 {unknown_type X; }; int main() { P1 p1 = {1}; P2 p2 = {1}; Check_x(p1); // must return true Check_x(p2); // must return false return 0; } </code>

template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }

struct P1 {int x; };
struct P2 {float X; };
// it also could be struct P3 {unknown_type X; };

int main()
{
    P1 p1 = {1};
    P2 p2 = {1};

    Check_x(p1); // must return true
    Check_x(p2); // must return false

    return 0;
}

But it does not compile in Visual Studio, while compiling in the GNU C++. With Visual Studio I could use the following template:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; }
</code>
<code> template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; } </code>

template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; }

But it does not compile in GNU C++. Is there universal solution?

UPD: Structures P1 and P2 here are only for example. There are could be any classes with unknown members.

P.S. Please, do not post C++11 solutions here because they are obvious and not relevant to the question.

6

Here is a solution simpler than
Johannes Schaub – litb’s one. It requires C++11.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <type_traits>
template <typename T, typename = int>
struct HasX : std::false_type { };
template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };
</code>
<code>#include <type_traits> template <typename T, typename = int> struct HasX : std::false_type { }; template <typename T> struct HasX <T, decltype((void) T::x, 0)> : std::true_type { }; </code>
#include <type_traits>

template <typename T, typename = int>
struct HasX : std::false_type { };

template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };

Update: A quick example and the explanation on how this works.

For these types:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>struct A { int x; };
struct B { int y; };
</code>
<code>struct A { int x; }; struct B { int y; }; </code>
struct A { int x; };
struct B { int y; };

we have HasX<A>::value == true and HasX<B>::value == false. Let’s see why.

First recall that std::false_type and std::true_type have a static constexpr bool member named value which is set to false and true, respectively. Hence, the two templates HasX above inherit this member. (The first template from std::false_type and the second one from std::true_type.)

Let’s start simple and then proceed step by step until we get to the code above.

1) Starting point:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>template <typename T, typename U>
struct HasX : std::false_type { };
</code>
<code>template <typename T, typename U> struct HasX : std::false_type { }; </code>
template <typename T, typename U>
struct HasX : std::false_type { };

In this case, there’s no surprise: HasX derives from std::false_type and hence HasX<bool, double>::value == false and HasX<bool, int>::value == false.

2) Defaulting U:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };
</code>
<code>// Primary template template <typename T, typename U = int> struct HasX : std::false_type { }; </code>
// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };

Given that U defaults to int, Has<bool> actually means HasX<bool, int> and thus, HasX<bool>::value == HasX<bool, int>::value == false.

3) Adding a specialization:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };
// Specialization for U = int
template <typename T>
struct HasX<T, int> : std::true_type { };
</code>
<code>// Primary template template <typename T, typename U = int> struct HasX : std::false_type { }; // Specialization for U = int template <typename T> struct HasX<T, int> : std::true_type { }; </code>
// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };

// Specialization for U = int
template <typename T>
struct HasX<T, int> : std::true_type { };

In general, thanks to the primary template, HasX<T, U> derives from std::false_type. However, there exists a specialization for U = int which derives from std::true_type. Therefore, HasX<bool, double>::value == false but HasX<bool, int>::value == true.

Thanks to the default for U, HasX<bool>::value == HasX<bool, int>::value == true.

4) decltype and a fancy way to say int:

A little digression here but, please, bear with me.

Basically (this is not entirely correct), decltype(expression) yields the type of expression. For instance, 0 has type int thus, decltype(0) means int. Analogously, 1.2 has type double and thus, decltype(1.2) means double.

Consider a function with this declaration:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>char func(foo, int);
</code>
<code>char func(foo, int); </code>
char func(foo, int);

where foo is some class type. If f is an object of type foo, then decltype(func(f, 0)) means char (the type returned by func(f, 0)).

Now, the expression (1.2, 0) uses the (built-in) comma operator which evaluates the two sub-expressions in order (that is, first 1.2 and then 0), discards the first value and results in the second one. Hence,

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>int x = (1.2, 0);
</code>
<code>int x = (1.2, 0); </code>
int x = (1.2, 0);

is equivalent to

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>int x = 0;
</code>
<code>int x = 0; </code>
int x = 0;

Putting this together with decltype gives that decltype(1.2, 0) means int. There’s nothing really special about 1.2 or double here. For instance, true has type bool and decltype(true, 0) means int as well.

What about a class type? For instace, what does decltype(f, 0) mean? It’s natural to expect that this still means int but it might not be the case. Indeed, there might be an overload for the comma operator similar to the function func above that takes a foo and an int and returns a char. In this case, decltype(foo, 0) is char.

How can we avoid the use of a overload for the comma operator? Well, there’s no way to overload the comma operator for a void operand and we can cast anything to void. Therefore, decltype((void) f, 0) means int. Indeed, (void) f casts f from foo to void which basically does nothing but saying that the expression must be considered as having type void. Then the built-in operator comma is used and ((void) f, 0) results in 0 which has type int. Hence, decltype((void) f, 0) means int.

Is this cast really necessary? Well, if there’s no overload for the comma operator taking foo and int then this isn’t necessary. We can always inspect the source code to see if there’s such operator or not. However, if this appear in a template and f has type V which is a template parameter, then it’s no longer clear (or even impossible to know) whether such overload for the comma operator exists or not. To be generic we cast anyway.

Bottom line: decltype((void) f, 0) is a fancy way to say int.

5) SFINAE:

This is a whole science 😉 OK I’m exagerating but it’s not very simple either. So I’ll keep the explanation to the bare minimum.

SFINAE stands for Substitution Failure is Not An Error. It means that when a template parameter is substituted by a type, an illegal C++ code might appear but, in some circunstances, instead of aborting compilation the compiler simply ignores the offending code as if it wasn’t there. Let’s see how it applies to our case:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };
// Specialization for U = int
template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };
</code>
<code>// Primary template template <typename T, typename U = int> struct HasX : std::false_type { }; // Specialization for U = int template <typename T> struct HasX <T, decltype((void) T::x, 0)> : std::true_type { }; </code>
// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };

// Specialization for U = int
template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };

Here, again, decltype((void) T::x, 0) is a fancy way to say int but with the benefit of SFINAE.

When T is substituted with a type, an invalid construct might appear. For instance, bool::x is not valid C++, so substituting T with bool in T::x yields an invalid construct. Under the SFINAE principle, the compiler doesn’t reject the code, it simply ignores (parts of) it. More precisely, as we have seenHasX<bool> means actually HasX<bool, int>. The specialization for U = int should be selected but, while instantiating it, the compiler finds bool::x and ignores the template specialization altogether as if it didn’t exist.

At this point, the code is essencially the same as in case (2) above where just the primary template exists. Hence, HasX<bool, int>::value == false.

The same argument used for bool holds for B since B::x is an invalid construct (B has no member x). However, A::x is OK and the compiler sees no issue in instantiating the specialization for U = int (or, more precisely, for U = decltype((void) A::x, 0)). Hence, HasX<A>::value == true.

6) Unnaming U:

Well, looking at the code in (5) again, we see that the name U is not used anywhere but in its declaration (typename U). We can then unname the second template argument and we obtain the code shown at the top of this post.

12

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>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
}
</code>
<code>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 } </code>
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.

15

I got redirected here from a question which has been closed as a duplicate of this one. I know it’s an old thread, but I just wanted to suggest an alternative (simpler?) implementation that works with C++11. Supposing we want to check whether a certain class has a member variable called id:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <type_traits>
template<typename T, typename = void>
struct has_id : std::false_type { };
template<typename T>
struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { };
</code>
<code>#include <type_traits> template<typename T, typename = void> struct has_id : std::false_type { }; template<typename T> struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { }; </code>
#include <type_traits>

template<typename T, typename = void>
struct has_id : std::false_type { };

template<typename T>
struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { };

That’s it. And here is how it would be used (live example):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <iostream>
using namespace std;
struct X { int id; };
struct Y { int foo; };
int main()
{
cout << boolalpha;
cout << has_id<X>::value << endl;
cout << has_id<Y>::value << endl;
}
</code>
<code>#include <iostream> using namespace std; struct X { int id; }; struct Y { int foo; }; int main() { cout << boolalpha; cout << has_id<X>::value << endl; cout << has_id<Y>::value << endl; } </code>
#include <iostream>

using namespace std;

struct X { int id; };
struct Y { int foo; };

int main()
{
    cout << boolalpha;
    cout << has_id<X>::value << endl;
    cout << has_id<Y>::value << endl;
}

Things can be made even simpler with a couple of macros:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#define DEFINE_MEMBER_CHECKER(member)
template<typename T, typename V = bool>
struct has_ ## member : false_type { };
template<typename T>
struct has_ ## member<T,
typename enable_if<
!is_same<decltype(declval<T>().member), void>::value,
bool
>::type
> : true_type { };
#define HAS_MEMBER(C, member)
has_ ## member<C>::value
</code>
<code>#define DEFINE_MEMBER_CHECKER(member) template<typename T, typename V = bool> struct has_ ## member : false_type { }; template<typename T> struct has_ ## member<T, typename enable_if< !is_same<decltype(declval<T>().member), void>::value, bool >::type > : true_type { }; #define HAS_MEMBER(C, member) has_ ## member<C>::value </code>
#define DEFINE_MEMBER_CHECKER(member) 
    template<typename T, typename V = bool> 
    struct has_ ## member : false_type { }; 
    template<typename T> 
    struct has_ ## member<T, 
        typename enable_if< 
            !is_same<decltype(declval<T>().member), void>::value, 
            bool 
            >::type 
        > : true_type { };

#define HAS_MEMBER(C, member) 
    has_ ## member<C>::value

Which could be used this way:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>using namespace std;
struct X { int id; };
struct Y { int foo; };
DEFINE_MEMBER_CHECKER(foo)
int main()
{
cout << boolalpha;
cout << HAS_MEMBER(X, foo) << endl;
cout << HAS_MEMBER(Y, foo) << endl;
}
</code>
<code>using namespace std; struct X { int id; }; struct Y { int foo; }; DEFINE_MEMBER_CHECKER(foo) int main() { cout << boolalpha; cout << HAS_MEMBER(X, foo) << endl; cout << HAS_MEMBER(Y, foo) << endl; } </code>
using namespace std;

struct X { int id; };
struct Y { int foo; };

DEFINE_MEMBER_CHECKER(foo)

int main()
{
    cout << boolalpha;
    cout << HAS_MEMBER(X, foo) << endl;
    cout << HAS_MEMBER(Y, foo) << endl;
}

2

We can use a C++20 requires expression to solve this problem. h/t to @lefticus who recently posted this method in C++ Weekly – Ep 242 – Design By Introspection in C++20 (concepts + if constexpr:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <iostream>
struct P1 {int x;};
struct P2 {float X;};
bool has_x(const auto &obj) {
if constexpr (requires {obj.x;}) {
return true;
} else
return false;
}
int main()
{
P1 p1 = {1};
P2 p2 = {1};
std::cout << std::boolalpha << has_x(p1) << "n";
std::cout << has_x(p2) << "n";
return 0;
}
</code>
<code>#include <iostream> struct P1 {int x;}; struct P2 {float X;}; bool has_x(const auto &obj) { if constexpr (requires {obj.x;}) { return true; } else return false; } int main() { P1 p1 = {1}; P2 p2 = {1}; std::cout << std::boolalpha << has_x(p1) << "n"; std::cout << has_x(p2) << "n"; return 0; } </code>
#include <iostream>

struct P1 {int x;};
struct P2 {float X;};

bool has_x(const auto &obj) {
    if constexpr (requires {obj.x;}) {
      return true;
    } else
      return false;
}

int main()
{
    P1 p1 = {1};
    P2 p2 = {1};

    std::cout << std::boolalpha << has_x(p1) << "n"; 
    std::cout << has_x(p2) << "n"; 

    return 0;
}

You can see it live here.

UPDATE: I’ve recently done some more with the code I posted in my original answer, so I’m updating this to account for changes/additions.

Here are some usage snippets:
*The guts for all this are farther down

Check for member x in a given class. Could be var, func, class, union, or enum:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CHECK(x);
bool has_x = has_member_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CHECK(x); bool has_x = has_member_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CHECK(x);
bool has_x = has_member_x<class_to_check_for_x>::value;

Check for member function void x():

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Func signature MUST have T as template variable here... simpler this way :
CREATE_MEMBER_FUNC_SIG_CHECK(x, void (T::*)(), void__x);
bool has_func_sig_void__x = has_member_func_void__x<class_to_check_for_x>::value;
</code>
<code>//Func signature MUST have T as template variable here... simpler this way : CREATE_MEMBER_FUNC_SIG_CHECK(x, void (T::*)(), void__x); bool has_func_sig_void__x = has_member_func_void__x<class_to_check_for_x>::value; </code>
//Func signature MUST have T as template variable here... simpler this way :
CREATE_MEMBER_FUNC_SIG_CHECK(x, void (T::*)(), void__x);
bool has_func_sig_void__x = has_member_func_void__x<class_to_check_for_x>::value;

Check for member variable x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_VAR_CHECK(x);
bool has_var_x = has_member_var_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_VAR_CHECK(x); bool has_var_x = has_member_var_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_VAR_CHECK(x);
bool has_var_x = has_member_var_x<class_to_check_for_x>::value;

Check for member class x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CLASS_CHECK(x);
bool has_class_x = has_member_class_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CLASS_CHECK(x); bool has_class_x = has_member_class_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CLASS_CHECK(x);
bool has_class_x = has_member_class_x<class_to_check_for_x>::value;

Check for member union x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_UNION_CHECK(x);
bool has_union_x = has_member_union_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_UNION_CHECK(x); bool has_union_x = has_member_union_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_UNION_CHECK(x);
bool has_union_x = has_member_union_x<class_to_check_for_x>::value;

Check for member enum x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_ENUM_CHECK(x);
bool has_enum_x = has_member_enum_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_ENUM_CHECK(x); bool has_enum_x = has_member_enum_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_ENUM_CHECK(x);
bool has_enum_x = has_member_enum_x<class_to_check_for_x>::value;

Check for any member function x regardless of signature:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CHECK(x);
CREATE_MEMBER_VAR_CHECK(x);
CREATE_MEMBER_CLASS_CHECK(x);
CREATE_MEMBER_UNION_CHECK(x);
CREATE_MEMBER_ENUM_CHECK(x);
CREATE_MEMBER_FUNC_CHECK(x);
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CHECK(x); CREATE_MEMBER_VAR_CHECK(x); CREATE_MEMBER_CLASS_CHECK(x); CREATE_MEMBER_UNION_CHECK(x); CREATE_MEMBER_ENUM_CHECK(x); CREATE_MEMBER_FUNC_CHECK(x); bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CHECK(x);
CREATE_MEMBER_VAR_CHECK(x);
CREATE_MEMBER_CLASS_CHECK(x);
CREATE_MEMBER_UNION_CHECK(x);
CREATE_MEMBER_ENUM_CHECK(x);
CREATE_MEMBER_FUNC_CHECK(x);
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;

OR

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CHECKS(x); //Just stamps out the same macro calls as above.
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CHECKS(x); //Just stamps out the same macro calls as above. bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CHECKS(x);  //Just stamps out the same macro calls as above.
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;

Details and core:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>/*
- Multiple inheritance forces ambiguity of member names.
- SFINAE is used to make aliases to member names.
- Expression SFINAE is used in just one generic has_member that can accept
any alias we pass it.
*/
template <typename... Args> struct ambiguate : public Args... {};
template<typename A, typename = void>
struct got_type : std::false_type {};
template<typename A>
struct got_type<A> : std::true_type {
typedef A type;
};
template<typename T, T>
struct sig_check : std::true_type {};
template<typename Alias, typename AmbiguitySeed>
struct has_member {
template<typename C> static char ((&f(decltype(&C::value))))[1];
template<typename C> static char ((&f(...)))[2];
//Make sure the member name is consistently spelled the same.
static_assert(
(sizeof(f<AmbiguitySeed>(0)) == 1)
, "Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong Alias/AmbiguitySeed has been specified."
);
static bool const value = sizeof(f<Alias>(0)) == 2;
};
</code>
<code>/* - Multiple inheritance forces ambiguity of member names. - SFINAE is used to make aliases to member names. - Expression SFINAE is used in just one generic has_member that can accept any alias we pass it. */ template <typename... Args> struct ambiguate : public Args... {}; template<typename A, typename = void> struct got_type : std::false_type {}; template<typename A> struct got_type<A> : std::true_type { typedef A type; }; template<typename T, T> struct sig_check : std::true_type {}; template<typename Alias, typename AmbiguitySeed> struct has_member { template<typename C> static char ((&f(decltype(&C::value))))[1]; template<typename C> static char ((&f(...)))[2]; //Make sure the member name is consistently spelled the same. static_assert( (sizeof(f<AmbiguitySeed>(0)) == 1) , "Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong Alias/AmbiguitySeed has been specified." ); static bool const value = sizeof(f<Alias>(0)) == 2; }; </code>
/*
    - Multiple inheritance forces ambiguity of member names.
    - SFINAE is used to make aliases to member names.
    - Expression SFINAE is used in just one generic has_member that can accept
      any alias we pass it.
*/

template <typename... Args> struct ambiguate : public Args... {};

template<typename A, typename = void>
struct got_type : std::false_type {};

template<typename A>
struct got_type<A> : std::true_type {
    typedef A type;
};

template<typename T, T>
struct sig_check : std::true_type {};

template<typename Alias, typename AmbiguitySeed>
struct has_member {
    template<typename C> static char ((&f(decltype(&C::value))))[1];
    template<typename C> static char ((&f(...)))[2];

    //Make sure the member name is consistently spelled the same.
    static_assert(
        (sizeof(f<AmbiguitySeed>(0)) == 1)
        , "Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong Alias/AmbiguitySeed has been specified."
    );

    static bool const value = sizeof(f<Alias>(0)) == 2;
};

Macros (El Diablo!):

CREATE_MEMBER_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for any member with given name, whether var, func, class, union, enum.
#define CREATE_MEMBER_CHECK(member)
template<typename T, typename = std::true_type>
struct Alias_##member;
template<typename T>
struct Alias_##member <
T, std::integral_constant<bool, got_type<decltype(&T::member)>::value>
> { static const decltype(&T::member) value; };
struct AmbiguitySeed_##member { char member; };
template<typename T>
struct has_member_##member {
static const bool value
= has_member<
Alias_##member<ambiguate<T, AmbiguitySeed_##member>>
, Alias_##member<AmbiguitySeed_##member>
>::value
;
}
</code>
<code>//Check for any member with given name, whether var, func, class, union, enum. #define CREATE_MEMBER_CHECK(member) template<typename T, typename = std::true_type> struct Alias_##member; template<typename T> struct Alias_##member < T, std::integral_constant<bool, got_type<decltype(&T::member)>::value> > { static const decltype(&T::member) value; }; struct AmbiguitySeed_##member { char member; }; template<typename T> struct has_member_##member { static const bool value = has_member< Alias_##member<ambiguate<T, AmbiguitySeed_##member>> , Alias_##member<AmbiguitySeed_##member> >::value ; } </code>
//Check for any member with given name, whether var, func, class, union, enum.
#define CREATE_MEMBER_CHECK(member)                                         
                                                                            
template<typename T, typename = std::true_type>                             
struct Alias_##member;                                                      
                                                                            
template<typename T>                                                        
struct Alias_##member <                                                     
    T, std::integral_constant<bool, got_type<decltype(&T::member)>::value>  
> { static const decltype(&T::member) value; };                             
                                                                            
struct AmbiguitySeed_##member { char member; };                             
                                                                            
template<typename T>                                                        
struct has_member_##member {                                                
    static const bool value                                                 
        = has_member<                                                       
            Alias_##member<ambiguate<T, AmbiguitySeed_##member>>            
            , Alias_##member<AmbiguitySeed_##member>                        
        >::value                                                            
    ;                                                                       
}

CREATE_MEMBER_VAR_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member variable with given name.
#define CREATE_MEMBER_VAR_CHECK(var_name)
template<typename T, typename = std::true_type>
struct has_member_var_##var_name : std::false_type {};
template<typename T>
struct has_member_var_##var_name<
T
, std::integral_constant<
bool
, !std::is_member_function_pointer<decltype(&T::var_name)>::value
>
> : std::true_type {}
</code>
<code>//Check for member variable with given name. #define CREATE_MEMBER_VAR_CHECK(var_name) template<typename T, typename = std::true_type> struct has_member_var_##var_name : std::false_type {}; template<typename T> struct has_member_var_##var_name< T , std::integral_constant< bool , !std::is_member_function_pointer<decltype(&T::var_name)>::value > > : std::true_type {} </code>
//Check for member variable with given name.
#define CREATE_MEMBER_VAR_CHECK(var_name)                                   
                                                                            
template<typename T, typename = std::true_type>                             
struct has_member_var_##var_name : std::false_type {};                      
                                                                            
template<typename T>                                                        
struct has_member_var_##var_name<                                           
    T                                                                       
    , std::integral_constant<                                               
        bool                                                                
        , !std::is_member_function_pointer<decltype(&T::var_name)>::value   
    >                                                                       
> : std::true_type {}

CREATE_MEMBER_FUNC_SIG_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member function with given name AND signature.
#define CREATE_MEMBER_FUNC_SIG_CHECK(func_name, func_sig, templ_postfix)
template<typename T, typename = std::true_type>
struct has_member_func_##templ_postfix : std::false_type {};
template<typename T>
struct has_member_func_##templ_postfix<
T, std::integral_constant<
bool
, sig_check<func_sig, &T::func_name>::value
>
> : std::true_type {}
</code>
<code>//Check for member function with given name AND signature. #define CREATE_MEMBER_FUNC_SIG_CHECK(func_name, func_sig, templ_postfix) template<typename T, typename = std::true_type> struct has_member_func_##templ_postfix : std::false_type {}; template<typename T> struct has_member_func_##templ_postfix< T, std::integral_constant< bool , sig_check<func_sig, &T::func_name>::value > > : std::true_type {} </code>
//Check for member function with given name AND signature.
#define CREATE_MEMBER_FUNC_SIG_CHECK(func_name, func_sig, templ_postfix)    
                                                                            
template<typename T, typename = std::true_type>                             
struct has_member_func_##templ_postfix : std::false_type {};                
                                                                            
template<typename T>                                                        
struct has_member_func_##templ_postfix<                                     
    T, std::integral_constant<                                              
        bool                                                                
        , sig_check<func_sig, &T::func_name>::value                         
    >                                                                       
> : std::true_type {}

CREATE_MEMBER_CLASS_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member class with given name.
#define CREATE_MEMBER_CLASS_CHECK(class_name)
template<typename T, typename = std::true_type>
struct has_member_class_##class_name : std::false_type {};
template<typename T>
struct has_member_class_##class_name<
T
, std::integral_constant<
bool
, std::is_class<
typename got_type<typename T::class_name>::type
>::value
>
> : std::true_type {}
</code>
<code>//Check for member class with given name. #define CREATE_MEMBER_CLASS_CHECK(class_name) template<typename T, typename = std::true_type> struct has_member_class_##class_name : std::false_type {}; template<typename T> struct has_member_class_##class_name< T , std::integral_constant< bool , std::is_class< typename got_type<typename T::class_name>::type >::value > > : std::true_type {} </code>
//Check for member class with given name.
#define CREATE_MEMBER_CLASS_CHECK(class_name)               
                                                            
template<typename T, typename = std::true_type>             
struct has_member_class_##class_name : std::false_type {};  
                                                            
template<typename T>                                        
struct has_member_class_##class_name<                       
    T                                                       
    , std::integral_constant<                               
        bool                                                
        , std::is_class<                                    
            typename got_type<typename T::class_name>::type 
        >::value                                            
    >                                                       
> : std::true_type {}

CREATE_MEMBER_UNION_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member union with given name.
#define CREATE_MEMBER_UNION_CHECK(union_name)
template<typename T, typename = std::true_type>
struct has_member_union_##union_name : std::false_type {};
template<typename T>
struct has_member_union_##union_name<
T
, std::integral_constant<
bool
, std::is_union<
typename got_type<typename T::union_name>::type
>::value
>
> : std::true_type {}
</code>
<code>//Check for member union with given name. #define CREATE_MEMBER_UNION_CHECK(union_name) template<typename T, typename = std::true_type> struct has_member_union_##union_name : std::false_type {}; template<typename T> struct has_member_union_##union_name< T , std::integral_constant< bool , std::is_union< typename got_type<typename T::union_name>::type >::value > > : std::true_type {} </code>
//Check for member union with given name.
#define CREATE_MEMBER_UNION_CHECK(union_name)               
                                                            
template<typename T, typename = std::true_type>             
struct has_member_union_##union_name : std::false_type {};  
                                                            
template<typename T>                                        
struct has_member_union_##union_name<                       
    T                                                       
    , std::integral_constant<                               
        bool                                                
        , std::is_union<                                    
            typename got_type<typename T::union_name>::type 
        >::value                                            
    >                                                       
> : std::true_type {}

CREATE_MEMBER_ENUM_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member enum with given name.
#define CREATE_MEMBER_ENUM_CHECK(enum_name)
template<typename T, typename = std::true_type>
struct has_member_enum_##enum_name : std::false_type {};
template<typename T>
struct has_member_enum_##enum_name<
T
, std::integral_constant<
bool
, std::is_enum<
typename got_type<typename T::enum_name>::type
>::value
>
> : std::true_type {}
</code>
<code>//Check for member enum with given name. #define CREATE_MEMBER_ENUM_CHECK(enum_name) template<typename T, typename = std::true_type> struct has_member_enum_##enum_name : std::false_type {}; template<typename T> struct has_member_enum_##enum_name< T , std::integral_constant< bool , std::is_enum< typename got_type<typename T::enum_name>::type >::value > > : std::true_type {} </code>
//Check for member enum with given name.
#define CREATE_MEMBER_ENUM_CHECK(enum_name)                 
                                                            
template<typename T, typename = std::true_type>             
struct has_member_enum_##enum_name : std::false_type {};    
                                                            
template<typename T>                                        
struct has_member_enum_##enum_name<                         
    T                                                       
    , std::integral_constant<                               
        bool                                                
        , std::is_enum<                                     
            typename got_type<typename T::enum_name>::type  
        >::value                                            
    >                                                       
> : std::true_type {}

CREATE_MEMBER_FUNC_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for function with given name, any signature.
#define CREATE_MEMBER_FUNC_CHECK(func)
template<typename T>
struct has_member_func_##func {
static const bool value
= has_member_##func<T>::value
&& !has_member_var_##func<T>::value
&& !has_member_class_##func<T>::value
&& !has_member_union_##func<T>::value
&& !has_member_enum_##func<T>::value
;
}
</code>
<code>//Check for function with given name, any signature. #define CREATE_MEMBER_FUNC_CHECK(func) template<typename T> struct has_member_func_##func { static const bool value = has_member_##func<T>::value && !has_member_var_##func<T>::value && !has_member_class_##func<T>::value && !has_member_union_##func<T>::value && !has_member_enum_##func<T>::value ; } </code>
//Check for function with given name, any signature.
#define CREATE_MEMBER_FUNC_CHECK(func)          
template<typename T>                            
struct has_member_func_##func {                 
    static const bool value                     
        = has_member_##func<T>::value           
        && !has_member_var_##func<T>::value     
        && !has_member_class_##func<T>::value   
        && !has_member_union_##func<T>::value   
        && !has_member_enum_##func<T>::value    
    ;                                           
}

CREATE_MEMBER_CHECKS:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Create all the checks for one member. Does NOT include func sig checks.
#define CREATE_MEMBER_CHECKS(member)
CREATE_MEMBER_CHECK(member);
CREATE_MEMBER_VAR_CHECK(member);
CREATE_MEMBER_CLASS_CHECK(member);
CREATE_MEMBER_UNION_CHECK(member);
CREATE_MEMBER_ENUM_CHECK(member);
CREATE_MEMBER_FUNC_CHECK(member)
</code>
<code>//Create all the checks for one member. Does NOT include func sig checks. #define CREATE_MEMBER_CHECKS(member) CREATE_MEMBER_CHECK(member); CREATE_MEMBER_VAR_CHECK(member); CREATE_MEMBER_CLASS_CHECK(member); CREATE_MEMBER_UNION_CHECK(member); CREATE_MEMBER_ENUM_CHECK(member); CREATE_MEMBER_FUNC_CHECK(member) </code>
//Create all the checks for one member.  Does NOT include func sig checks.
#define CREATE_MEMBER_CHECKS(member)    
CREATE_MEMBER_CHECK(member);            
CREATE_MEMBER_VAR_CHECK(member);        
CREATE_MEMBER_CLASS_CHECK(member);      
CREATE_MEMBER_UNION_CHECK(member);      
CREATE_MEMBER_ENUM_CHECK(member);       
CREATE_MEMBER_FUNC_CHECK(member)

2

Boost.ConceptTraits provides between others some macros to define type traits, as for example BOOST_TT_EXT_DEFINE_HAS_MEMBER(name), which defines a type trait of the form:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>has_member_##name<T>
</code>
<code>has_member_##name<T> </code>
has_member_##name<T>

This gives true if T has a member type named . Note, however, that this won’t detect reference type members.

In you case it will be enough to add in a header file

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x)
</code>
<code>BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x) </code>
BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x)

and check as follows

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>BOOST_STATIC_ASSERT(has_member_x<P1>::value);
</code>
<code>BOOST_STATIC_ASSERT(has_member_x<P1>::value); </code>
BOOST_STATIC_ASSERT(has_member_x<P1>::value);

The technique used is the same as the one explained on some of the preceding answers.

Unfortunately this library is no more maintained. Now that C++0x will not includes concept, this library together with SFINAE is a perfect replacement to work with most of the concepts.

2

Why don’t you use specialization like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>struct P1 {int x; };
struct P2 {int X; };
template<class P>
bool Check_x(P p) { return true; }
template<>
bool Check_x<P2>(P2 p) { return false; }
</code>
<code>struct P1 {int x; }; struct P2 {int X; }; template<class P> bool Check_x(P p) { return true; } template<> bool Check_x<P2>(P2 p) { return false; } </code>
struct P1 {int x; };
struct P2 {int X; };

template<class P> 
bool Check_x(P p) { return true; }

template<> 
bool Check_x<P2>(P2 p) { return false; }

3

Are the functions (x, X, y, Y) from an abstract base class, or could they be refactored to be so? If so you can use the SUPERSUBCLASS() macro from Modern C++ Design, along with ideas from the answer to this question:

Compile-time type based dispatch

Why don’t you just create template specializations of Check_x ?

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>template<> bool Check_x(P1 p) { return true; }
template<> bool Check_x(P2 p) { return false; }
</code>
<code>template<> bool Check_x(P1 p) { return true; } template<> bool Check_x(P2 p) { return false; } </code>
template<> bool Check_x(P1 p) { return true; }
template<> bool Check_x(P2 p) { return false; }

Heck, when I think of it. If you only have two types, why do you even need templates for this?

1

We can get at compile time: 0 - not_member, 1 - is_object, 2 - is_function for each required class and member – object or function: http://ideone.com/Fjm9u5

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <iostream>
#include <type_traits>
#define IS_MEMBER(T1, M)
struct {
struct verystrangename1 { bool M; };
template<typename T> struct verystrangename2 : verystrangename1, public T { };
enum return_t { not_member, is_object, is_function };
template<typename T, typename = decltype(verystrangename2<T>::M)> constexpr return_t what_member() { return not_member; }
template<typename T> typename std::enable_if<std::is_member_object_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_object; }
template<typename T> typename std::enable_if<std::is_member_function_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_function; }
constexpr operator return_t() { return what_member<T1>(); }
}
struct t {
int aaa;
float bbb;
void func() {}
};
// Can't be in function
IS_MEMBER(t, aaa) is_aaa_member_of_t;
IS_MEMBER(t, ccc) is_ccc_member_of_t;
IS_MEMBER(t, func) is_func_member_of_t;
// known at compile time
enum { const_is_aaa_member_of_t = (int)is_aaa_member_of_t };
static constexpr int const_is_func_member_of_t = is_func_member_of_t;
int main() {
std::cout << std::boolalpha << "0 - not_member, 1 - is_object, 2 - is_function nn" <<
"is aaa member of t = " << is_aaa_member_of_t << std::endl <<
"is ccc member of t = " << is_ccc_member_of_t << std::endl <<
"is func member of t = " << is_func_member_of_t << std::endl <<
std::endl;
return 0;
}
</code>
<code>#include <iostream> #include <type_traits> #define IS_MEMBER(T1, M) struct { struct verystrangename1 { bool M; }; template<typename T> struct verystrangename2 : verystrangename1, public T { }; enum return_t { not_member, is_object, is_function }; template<typename T, typename = decltype(verystrangename2<T>::M)> constexpr return_t what_member() { return not_member; } template<typename T> typename std::enable_if<std::is_member_object_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_object; } template<typename T> typename std::enable_if<std::is_member_function_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_function; } constexpr operator return_t() { return what_member<T1>(); } } struct t { int aaa; float bbb; void func() {} }; // Can't be in function IS_MEMBER(t, aaa) is_aaa_member_of_t; IS_MEMBER(t, ccc) is_ccc_member_of_t; IS_MEMBER(t, func) is_func_member_of_t; // known at compile time enum { const_is_aaa_member_of_t = (int)is_aaa_member_of_t }; static constexpr int const_is_func_member_of_t = is_func_member_of_t; int main() { std::cout << std::boolalpha << "0 - not_member, 1 - is_object, 2 - is_function nn" << "is aaa member of t = " << is_aaa_member_of_t << std::endl << "is ccc member of t = " << is_ccc_member_of_t << std::endl << "is func member of t = " << is_func_member_of_t << std::endl << std::endl; return 0; } </code>
#include <iostream>
#include <type_traits>

#define IS_MEMBER(T1, M)    
struct {        
    struct verystrangename1 { bool M; };    
    template<typename T> struct verystrangename2 : verystrangename1, public T { }; 
    
    enum return_t { not_member, is_object, is_function }; 
    template<typename T, typename = decltype(verystrangename2<T>::M)> constexpr return_t what_member() { return not_member;  }  
    template<typename T> typename std::enable_if<std::is_member_object_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_object; }   
    template<typename T> typename std::enable_if<std::is_member_function_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_function; }   
    constexpr operator return_t() { return what_member<T1>(); } 
}

struct t {
    int aaa;
    float bbb;
    void func() {}
};

// Can't be in function
IS_MEMBER(t, aaa) is_aaa_member_of_t;
IS_MEMBER(t, ccc) is_ccc_member_of_t;
IS_MEMBER(t, func) is_func_member_of_t;

// known at compile time
enum { const_is_aaa_member_of_t = (int)is_aaa_member_of_t };
static constexpr int const_is_func_member_of_t = is_func_member_of_t;

int main() {        
    std::cout << std::boolalpha << "0 - not_member, 1 - is_object, 2 - is_function nn" <<
        "is aaa member of t = " << is_aaa_member_of_t << std::endl << 
        "is ccc member of t = " << is_ccc_member_of_t << std::endl << 
        "is func member of t = " << is_func_member_of_t << std::endl << 
        std::endl;

    return 0;
}

Result:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>0 - not_member, 1 - is_object, 2 - is_function
is aaa member of t = 1
is ccc member of t = 0
is func member of t = 2
</code>
<code>0 - not_member, 1 - is_object, 2 - is_function is aaa member of t = 1 is ccc member of t = 0 is func member of t = 2 </code>
0 - not_member, 1 - is_object, 2 - is_function 

is aaa member of t = 1
is ccc member of t = 0
is func member of t = 2

For class/struct:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>struct t {
int aaa;
float bbb;
void func() {}
};
</code>
<code>struct t { int aaa; float bbb; void func() {} }; </code>
struct t {
    int aaa;
    float bbb;
    void func() {}
};

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

How to detect whether there is a specific member variable in class?

For creating algorithm template function I need to know whether x or X (and y or Y) in class that is template argument. It may by useful when using my function for MFC CPoint class or GDI+ PointF class or some others. All of them use different x in them. My solution could be reduces to the following code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }
struct P1 {int x; };
struct P2 {float X; };
// it also could be struct P3 {unknown_type X; };
int main()
{
P1 p1 = {1};
P2 p2 = {1};
Check_x(p1); // must return true
Check_x(p2); // must return false
return 0;
}
</code>
<code> template<int> struct TT {typedef int type;}; template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; } struct P1 {int x; }; struct P2 {float X; }; // it also could be struct P3 {unknown_type X; }; int main() { P1 p1 = {1}; P2 p2 = {1}; Check_x(p1); // must return true Check_x(p2); // must return false return 0; } </code>

template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }

struct P1 {int x; };
struct P2 {float X; };
// it also could be struct P3 {unknown_type X; };

int main()
{
    P1 p1 = {1};
    P2 p2 = {1};

    Check_x(p1); // must return true
    Check_x(p2); // must return false

    return 0;
}

But it does not compile in Visual Studio, while compiling in the GNU C++. With Visual Studio I could use the following template:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; }
</code>
<code> template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; } </code>

template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<&P::X==&P::X>::type b = 0) { return false; }

But it does not compile in GNU C++. Is there universal solution?

UPD: Structures P1 and P2 here are only for example. There are could be any classes with unknown members.

P.S. Please, do not post C++11 solutions here because they are obvious and not relevant to the question.

6

Here is a solution simpler than
Johannes Schaub – litb’s one. It requires C++11.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <type_traits>
template <typename T, typename = int>
struct HasX : std::false_type { };
template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };
</code>
<code>#include <type_traits> template <typename T, typename = int> struct HasX : std::false_type { }; template <typename T> struct HasX <T, decltype((void) T::x, 0)> : std::true_type { }; </code>
#include <type_traits>

template <typename T, typename = int>
struct HasX : std::false_type { };

template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };

Update: A quick example and the explanation on how this works.

For these types:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>struct A { int x; };
struct B { int y; };
</code>
<code>struct A { int x; }; struct B { int y; }; </code>
struct A { int x; };
struct B { int y; };

we have HasX<A>::value == true and HasX<B>::value == false. Let’s see why.

First recall that std::false_type and std::true_type have a static constexpr bool member named value which is set to false and true, respectively. Hence, the two templates HasX above inherit this member. (The first template from std::false_type and the second one from std::true_type.)

Let’s start simple and then proceed step by step until we get to the code above.

1) Starting point:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>template <typename T, typename U>
struct HasX : std::false_type { };
</code>
<code>template <typename T, typename U> struct HasX : std::false_type { }; </code>
template <typename T, typename U>
struct HasX : std::false_type { };

In this case, there’s no surprise: HasX derives from std::false_type and hence HasX<bool, double>::value == false and HasX<bool, int>::value == false.

2) Defaulting U:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };
</code>
<code>// Primary template template <typename T, typename U = int> struct HasX : std::false_type { }; </code>
// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };

Given that U defaults to int, Has<bool> actually means HasX<bool, int> and thus, HasX<bool>::value == HasX<bool, int>::value == false.

3) Adding a specialization:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };
// Specialization for U = int
template <typename T>
struct HasX<T, int> : std::true_type { };
</code>
<code>// Primary template template <typename T, typename U = int> struct HasX : std::false_type { }; // Specialization for U = int template <typename T> struct HasX<T, int> : std::true_type { }; </code>
// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };

// Specialization for U = int
template <typename T>
struct HasX<T, int> : std::true_type { };

In general, thanks to the primary template, HasX<T, U> derives from std::false_type. However, there exists a specialization for U = int which derives from std::true_type. Therefore, HasX<bool, double>::value == false but HasX<bool, int>::value == true.

Thanks to the default for U, HasX<bool>::value == HasX<bool, int>::value == true.

4) decltype and a fancy way to say int:

A little digression here but, please, bear with me.

Basically (this is not entirely correct), decltype(expression) yields the type of expression. For instance, 0 has type int thus, decltype(0) means int. Analogously, 1.2 has type double and thus, decltype(1.2) means double.

Consider a function with this declaration:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>char func(foo, int);
</code>
<code>char func(foo, int); </code>
char func(foo, int);

where foo is some class type. If f is an object of type foo, then decltype(func(f, 0)) means char (the type returned by func(f, 0)).

Now, the expression (1.2, 0) uses the (built-in) comma operator which evaluates the two sub-expressions in order (that is, first 1.2 and then 0), discards the first value and results in the second one. Hence,

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>int x = (1.2, 0);
</code>
<code>int x = (1.2, 0); </code>
int x = (1.2, 0);

is equivalent to

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>int x = 0;
</code>
<code>int x = 0; </code>
int x = 0;

Putting this together with decltype gives that decltype(1.2, 0) means int. There’s nothing really special about 1.2 or double here. For instance, true has type bool and decltype(true, 0) means int as well.

What about a class type? For instace, what does decltype(f, 0) mean? It’s natural to expect that this still means int but it might not be the case. Indeed, there might be an overload for the comma operator similar to the function func above that takes a foo and an int and returns a char. In this case, decltype(foo, 0) is char.

How can we avoid the use of a overload for the comma operator? Well, there’s no way to overload the comma operator for a void operand and we can cast anything to void. Therefore, decltype((void) f, 0) means int. Indeed, (void) f casts f from foo to void which basically does nothing but saying that the expression must be considered as having type void. Then the built-in operator comma is used and ((void) f, 0) results in 0 which has type int. Hence, decltype((void) f, 0) means int.

Is this cast really necessary? Well, if there’s no overload for the comma operator taking foo and int then this isn’t necessary. We can always inspect the source code to see if there’s such operator or not. However, if this appear in a template and f has type V which is a template parameter, then it’s no longer clear (or even impossible to know) whether such overload for the comma operator exists or not. To be generic we cast anyway.

Bottom line: decltype((void) f, 0) is a fancy way to say int.

5) SFINAE:

This is a whole science 😉 OK I’m exagerating but it’s not very simple either. So I’ll keep the explanation to the bare minimum.

SFINAE stands for Substitution Failure is Not An Error. It means that when a template parameter is substituted by a type, an illegal C++ code might appear but, in some circunstances, instead of aborting compilation the compiler simply ignores the offending code as if it wasn’t there. Let’s see how it applies to our case:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };
// Specialization for U = int
template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };
</code>
<code>// Primary template template <typename T, typename U = int> struct HasX : std::false_type { }; // Specialization for U = int template <typename T> struct HasX <T, decltype((void) T::x, 0)> : std::true_type { }; </code>
// Primary template
template <typename T, typename U = int>
struct HasX : std::false_type { };

// Specialization for U = int
template <typename T>
struct HasX <T, decltype((void) T::x, 0)> : std::true_type { };

Here, again, decltype((void) T::x, 0) is a fancy way to say int but with the benefit of SFINAE.

When T is substituted with a type, an invalid construct might appear. For instance, bool::x is not valid C++, so substituting T with bool in T::x yields an invalid construct. Under the SFINAE principle, the compiler doesn’t reject the code, it simply ignores (parts of) it. More precisely, as we have seenHasX<bool> means actually HasX<bool, int>. The specialization for U = int should be selected but, while instantiating it, the compiler finds bool::x and ignores the template specialization altogether as if it didn’t exist.

At this point, the code is essencially the same as in case (2) above where just the primary template exists. Hence, HasX<bool, int>::value == false.

The same argument used for bool holds for B since B::x is an invalid construct (B has no member x). However, A::x is OK and the compiler sees no issue in instantiating the specialization for U = int (or, more precisely, for U = decltype((void) A::x, 0)). Hence, HasX<A>::value == true.

6) Unnaming U:

Well, looking at the code in (5) again, we see that the name U is not used anywhere but in its declaration (typename U). We can then unname the second template argument and we obtain the code shown at the top of this post.

12

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>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
}
</code>
<code>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 } </code>
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.

15

I got redirected here from a question which has been closed as a duplicate of this one. I know it’s an old thread, but I just wanted to suggest an alternative (simpler?) implementation that works with C++11. Supposing we want to check whether a certain class has a member variable called id:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <type_traits>
template<typename T, typename = void>
struct has_id : std::false_type { };
template<typename T>
struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { };
</code>
<code>#include <type_traits> template<typename T, typename = void> struct has_id : std::false_type { }; template<typename T> struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { }; </code>
#include <type_traits>

template<typename T, typename = void>
struct has_id : std::false_type { };

template<typename T>
struct has_id<T, decltype(std::declval<T>().id, void())> : std::true_type { };

That’s it. And here is how it would be used (live example):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <iostream>
using namespace std;
struct X { int id; };
struct Y { int foo; };
int main()
{
cout << boolalpha;
cout << has_id<X>::value << endl;
cout << has_id<Y>::value << endl;
}
</code>
<code>#include <iostream> using namespace std; struct X { int id; }; struct Y { int foo; }; int main() { cout << boolalpha; cout << has_id<X>::value << endl; cout << has_id<Y>::value << endl; } </code>
#include <iostream>

using namespace std;

struct X { int id; };
struct Y { int foo; };

int main()
{
    cout << boolalpha;
    cout << has_id<X>::value << endl;
    cout << has_id<Y>::value << endl;
}

Things can be made even simpler with a couple of macros:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#define DEFINE_MEMBER_CHECKER(member)
template<typename T, typename V = bool>
struct has_ ## member : false_type { };
template<typename T>
struct has_ ## member<T,
typename enable_if<
!is_same<decltype(declval<T>().member), void>::value,
bool
>::type
> : true_type { };
#define HAS_MEMBER(C, member)
has_ ## member<C>::value
</code>
<code>#define DEFINE_MEMBER_CHECKER(member) template<typename T, typename V = bool> struct has_ ## member : false_type { }; template<typename T> struct has_ ## member<T, typename enable_if< !is_same<decltype(declval<T>().member), void>::value, bool >::type > : true_type { }; #define HAS_MEMBER(C, member) has_ ## member<C>::value </code>
#define DEFINE_MEMBER_CHECKER(member) 
    template<typename T, typename V = bool> 
    struct has_ ## member : false_type { }; 
    template<typename T> 
    struct has_ ## member<T, 
        typename enable_if< 
            !is_same<decltype(declval<T>().member), void>::value, 
            bool 
            >::type 
        > : true_type { };

#define HAS_MEMBER(C, member) 
    has_ ## member<C>::value

Which could be used this way:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>using namespace std;
struct X { int id; };
struct Y { int foo; };
DEFINE_MEMBER_CHECKER(foo)
int main()
{
cout << boolalpha;
cout << HAS_MEMBER(X, foo) << endl;
cout << HAS_MEMBER(Y, foo) << endl;
}
</code>
<code>using namespace std; struct X { int id; }; struct Y { int foo; }; DEFINE_MEMBER_CHECKER(foo) int main() { cout << boolalpha; cout << HAS_MEMBER(X, foo) << endl; cout << HAS_MEMBER(Y, foo) << endl; } </code>
using namespace std;

struct X { int id; };
struct Y { int foo; };

DEFINE_MEMBER_CHECKER(foo)

int main()
{
    cout << boolalpha;
    cout << HAS_MEMBER(X, foo) << endl;
    cout << HAS_MEMBER(Y, foo) << endl;
}

2

We can use a C++20 requires expression to solve this problem. h/t to @lefticus who recently posted this method in C++ Weekly – Ep 242 – Design By Introspection in C++20 (concepts + if constexpr:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <iostream>
struct P1 {int x;};
struct P2 {float X;};
bool has_x(const auto &obj) {
if constexpr (requires {obj.x;}) {
return true;
} else
return false;
}
int main()
{
P1 p1 = {1};
P2 p2 = {1};
std::cout << std::boolalpha << has_x(p1) << "n";
std::cout << has_x(p2) << "n";
return 0;
}
</code>
<code>#include <iostream> struct P1 {int x;}; struct P2 {float X;}; bool has_x(const auto &obj) { if constexpr (requires {obj.x;}) { return true; } else return false; } int main() { P1 p1 = {1}; P2 p2 = {1}; std::cout << std::boolalpha << has_x(p1) << "n"; std::cout << has_x(p2) << "n"; return 0; } </code>
#include <iostream>

struct P1 {int x;};
struct P2 {float X;};

bool has_x(const auto &obj) {
    if constexpr (requires {obj.x;}) {
      return true;
    } else
      return false;
}

int main()
{
    P1 p1 = {1};
    P2 p2 = {1};

    std::cout << std::boolalpha << has_x(p1) << "n"; 
    std::cout << has_x(p2) << "n"; 

    return 0;
}

You can see it live here.

UPDATE: I’ve recently done some more with the code I posted in my original answer, so I’m updating this to account for changes/additions.

Here are some usage snippets:
*The guts for all this are farther down

Check for member x in a given class. Could be var, func, class, union, or enum:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CHECK(x);
bool has_x = has_member_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CHECK(x); bool has_x = has_member_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CHECK(x);
bool has_x = has_member_x<class_to_check_for_x>::value;

Check for member function void x():

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Func signature MUST have T as template variable here... simpler this way :
CREATE_MEMBER_FUNC_SIG_CHECK(x, void (T::*)(), void__x);
bool has_func_sig_void__x = has_member_func_void__x<class_to_check_for_x>::value;
</code>
<code>//Func signature MUST have T as template variable here... simpler this way : CREATE_MEMBER_FUNC_SIG_CHECK(x, void (T::*)(), void__x); bool has_func_sig_void__x = has_member_func_void__x<class_to_check_for_x>::value; </code>
//Func signature MUST have T as template variable here... simpler this way :
CREATE_MEMBER_FUNC_SIG_CHECK(x, void (T::*)(), void__x);
bool has_func_sig_void__x = has_member_func_void__x<class_to_check_for_x>::value;

Check for member variable x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_VAR_CHECK(x);
bool has_var_x = has_member_var_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_VAR_CHECK(x); bool has_var_x = has_member_var_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_VAR_CHECK(x);
bool has_var_x = has_member_var_x<class_to_check_for_x>::value;

Check for member class x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CLASS_CHECK(x);
bool has_class_x = has_member_class_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CLASS_CHECK(x); bool has_class_x = has_member_class_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CLASS_CHECK(x);
bool has_class_x = has_member_class_x<class_to_check_for_x>::value;

Check for member union x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_UNION_CHECK(x);
bool has_union_x = has_member_union_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_UNION_CHECK(x); bool has_union_x = has_member_union_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_UNION_CHECK(x);
bool has_union_x = has_member_union_x<class_to_check_for_x>::value;

Check for member enum x:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_ENUM_CHECK(x);
bool has_enum_x = has_member_enum_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_ENUM_CHECK(x); bool has_enum_x = has_member_enum_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_ENUM_CHECK(x);
bool has_enum_x = has_member_enum_x<class_to_check_for_x>::value;

Check for any member function x regardless of signature:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CHECK(x);
CREATE_MEMBER_VAR_CHECK(x);
CREATE_MEMBER_CLASS_CHECK(x);
CREATE_MEMBER_UNION_CHECK(x);
CREATE_MEMBER_ENUM_CHECK(x);
CREATE_MEMBER_FUNC_CHECK(x);
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CHECK(x); CREATE_MEMBER_VAR_CHECK(x); CREATE_MEMBER_CLASS_CHECK(x); CREATE_MEMBER_UNION_CHECK(x); CREATE_MEMBER_ENUM_CHECK(x); CREATE_MEMBER_FUNC_CHECK(x); bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CHECK(x);
CREATE_MEMBER_VAR_CHECK(x);
CREATE_MEMBER_CLASS_CHECK(x);
CREATE_MEMBER_UNION_CHECK(x);
CREATE_MEMBER_ENUM_CHECK(x);
CREATE_MEMBER_FUNC_CHECK(x);
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;

OR

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE_MEMBER_CHECKS(x); //Just stamps out the same macro calls as above.
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;
</code>
<code>CREATE_MEMBER_CHECKS(x); //Just stamps out the same macro calls as above. bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value; </code>
CREATE_MEMBER_CHECKS(x);  //Just stamps out the same macro calls as above.
bool has_any_func_x = has_member_func_x<class_to_check_for_x>::value;

Details and core:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>/*
- Multiple inheritance forces ambiguity of member names.
- SFINAE is used to make aliases to member names.
- Expression SFINAE is used in just one generic has_member that can accept
any alias we pass it.
*/
template <typename... Args> struct ambiguate : public Args... {};
template<typename A, typename = void>
struct got_type : std::false_type {};
template<typename A>
struct got_type<A> : std::true_type {
typedef A type;
};
template<typename T, T>
struct sig_check : std::true_type {};
template<typename Alias, typename AmbiguitySeed>
struct has_member {
template<typename C> static char ((&f(decltype(&C::value))))[1];
template<typename C> static char ((&f(...)))[2];
//Make sure the member name is consistently spelled the same.
static_assert(
(sizeof(f<AmbiguitySeed>(0)) == 1)
, "Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong Alias/AmbiguitySeed has been specified."
);
static bool const value = sizeof(f<Alias>(0)) == 2;
};
</code>
<code>/* - Multiple inheritance forces ambiguity of member names. - SFINAE is used to make aliases to member names. - Expression SFINAE is used in just one generic has_member that can accept any alias we pass it. */ template <typename... Args> struct ambiguate : public Args... {}; template<typename A, typename = void> struct got_type : std::false_type {}; template<typename A> struct got_type<A> : std::true_type { typedef A type; }; template<typename T, T> struct sig_check : std::true_type {}; template<typename Alias, typename AmbiguitySeed> struct has_member { template<typename C> static char ((&f(decltype(&C::value))))[1]; template<typename C> static char ((&f(...)))[2]; //Make sure the member name is consistently spelled the same. static_assert( (sizeof(f<AmbiguitySeed>(0)) == 1) , "Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong Alias/AmbiguitySeed has been specified." ); static bool const value = sizeof(f<Alias>(0)) == 2; }; </code>
/*
    - Multiple inheritance forces ambiguity of member names.
    - SFINAE is used to make aliases to member names.
    - Expression SFINAE is used in just one generic has_member that can accept
      any alias we pass it.
*/

template <typename... Args> struct ambiguate : public Args... {};

template<typename A, typename = void>
struct got_type : std::false_type {};

template<typename A>
struct got_type<A> : std::true_type {
    typedef A type;
};

template<typename T, T>
struct sig_check : std::true_type {};

template<typename Alias, typename AmbiguitySeed>
struct has_member {
    template<typename C> static char ((&f(decltype(&C::value))))[1];
    template<typename C> static char ((&f(...)))[2];

    //Make sure the member name is consistently spelled the same.
    static_assert(
        (sizeof(f<AmbiguitySeed>(0)) == 1)
        , "Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong Alias/AmbiguitySeed has been specified."
    );

    static bool const value = sizeof(f<Alias>(0)) == 2;
};

Macros (El Diablo!):

CREATE_MEMBER_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for any member with given name, whether var, func, class, union, enum.
#define CREATE_MEMBER_CHECK(member)
template<typename T, typename = std::true_type>
struct Alias_##member;
template<typename T>
struct Alias_##member <
T, std::integral_constant<bool, got_type<decltype(&T::member)>::value>
> { static const decltype(&T::member) value; };
struct AmbiguitySeed_##member { char member; };
template<typename T>
struct has_member_##member {
static const bool value
= has_member<
Alias_##member<ambiguate<T, AmbiguitySeed_##member>>
, Alias_##member<AmbiguitySeed_##member>
>::value
;
}
</code>
<code>//Check for any member with given name, whether var, func, class, union, enum. #define CREATE_MEMBER_CHECK(member) template<typename T, typename = std::true_type> struct Alias_##member; template<typename T> struct Alias_##member < T, std::integral_constant<bool, got_type<decltype(&T::member)>::value> > { static const decltype(&T::member) value; }; struct AmbiguitySeed_##member { char member; }; template<typename T> struct has_member_##member { static const bool value = has_member< Alias_##member<ambiguate<T, AmbiguitySeed_##member>> , Alias_##member<AmbiguitySeed_##member> >::value ; } </code>
//Check for any member with given name, whether var, func, class, union, enum.
#define CREATE_MEMBER_CHECK(member)                                         
                                                                            
template<typename T, typename = std::true_type>                             
struct Alias_##member;                                                      
                                                                            
template<typename T>                                                        
struct Alias_##member <                                                     
    T, std::integral_constant<bool, got_type<decltype(&T::member)>::value>  
> { static const decltype(&T::member) value; };                             
                                                                            
struct AmbiguitySeed_##member { char member; };                             
                                                                            
template<typename T>                                                        
struct has_member_##member {                                                
    static const bool value                                                 
        = has_member<                                                       
            Alias_##member<ambiguate<T, AmbiguitySeed_##member>>            
            , Alias_##member<AmbiguitySeed_##member>                        
        >::value                                                            
    ;                                                                       
}

CREATE_MEMBER_VAR_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member variable with given name.
#define CREATE_MEMBER_VAR_CHECK(var_name)
template<typename T, typename = std::true_type>
struct has_member_var_##var_name : std::false_type {};
template<typename T>
struct has_member_var_##var_name<
T
, std::integral_constant<
bool
, !std::is_member_function_pointer<decltype(&T::var_name)>::value
>
> : std::true_type {}
</code>
<code>//Check for member variable with given name. #define CREATE_MEMBER_VAR_CHECK(var_name) template<typename T, typename = std::true_type> struct has_member_var_##var_name : std::false_type {}; template<typename T> struct has_member_var_##var_name< T , std::integral_constant< bool , !std::is_member_function_pointer<decltype(&T::var_name)>::value > > : std::true_type {} </code>
//Check for member variable with given name.
#define CREATE_MEMBER_VAR_CHECK(var_name)                                   
                                                                            
template<typename T, typename = std::true_type>                             
struct has_member_var_##var_name : std::false_type {};                      
                                                                            
template<typename T>                                                        
struct has_member_var_##var_name<                                           
    T                                                                       
    , std::integral_constant<                                               
        bool                                                                
        , !std::is_member_function_pointer<decltype(&T::var_name)>::value   
    >                                                                       
> : std::true_type {}

CREATE_MEMBER_FUNC_SIG_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member function with given name AND signature.
#define CREATE_MEMBER_FUNC_SIG_CHECK(func_name, func_sig, templ_postfix)
template<typename T, typename = std::true_type>
struct has_member_func_##templ_postfix : std::false_type {};
template<typename T>
struct has_member_func_##templ_postfix<
T, std::integral_constant<
bool
, sig_check<func_sig, &T::func_name>::value
>
> : std::true_type {}
</code>
<code>//Check for member function with given name AND signature. #define CREATE_MEMBER_FUNC_SIG_CHECK(func_name, func_sig, templ_postfix) template<typename T, typename = std::true_type> struct has_member_func_##templ_postfix : std::false_type {}; template<typename T> struct has_member_func_##templ_postfix< T, std::integral_constant< bool , sig_check<func_sig, &T::func_name>::value > > : std::true_type {} </code>
//Check for member function with given name AND signature.
#define CREATE_MEMBER_FUNC_SIG_CHECK(func_name, func_sig, templ_postfix)    
                                                                            
template<typename T, typename = std::true_type>                             
struct has_member_func_##templ_postfix : std::false_type {};                
                                                                            
template<typename T>                                                        
struct has_member_func_##templ_postfix<                                     
    T, std::integral_constant<                                              
        bool                                                                
        , sig_check<func_sig, &T::func_name>::value                         
    >                                                                       
> : std::true_type {}

CREATE_MEMBER_CLASS_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member class with given name.
#define CREATE_MEMBER_CLASS_CHECK(class_name)
template<typename T, typename = std::true_type>
struct has_member_class_##class_name : std::false_type {};
template<typename T>
struct has_member_class_##class_name<
T
, std::integral_constant<
bool
, std::is_class<
typename got_type<typename T::class_name>::type
>::value
>
> : std::true_type {}
</code>
<code>//Check for member class with given name. #define CREATE_MEMBER_CLASS_CHECK(class_name) template<typename T, typename = std::true_type> struct has_member_class_##class_name : std::false_type {}; template<typename T> struct has_member_class_##class_name< T , std::integral_constant< bool , std::is_class< typename got_type<typename T::class_name>::type >::value > > : std::true_type {} </code>
//Check for member class with given name.
#define CREATE_MEMBER_CLASS_CHECK(class_name)               
                                                            
template<typename T, typename = std::true_type>             
struct has_member_class_##class_name : std::false_type {};  
                                                            
template<typename T>                                        
struct has_member_class_##class_name<                       
    T                                                       
    , std::integral_constant<                               
        bool                                                
        , std::is_class<                                    
            typename got_type<typename T::class_name>::type 
        >::value                                            
    >                                                       
> : std::true_type {}

CREATE_MEMBER_UNION_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member union with given name.
#define CREATE_MEMBER_UNION_CHECK(union_name)
template<typename T, typename = std::true_type>
struct has_member_union_##union_name : std::false_type {};
template<typename T>
struct has_member_union_##union_name<
T
, std::integral_constant<
bool
, std::is_union<
typename got_type<typename T::union_name>::type
>::value
>
> : std::true_type {}
</code>
<code>//Check for member union with given name. #define CREATE_MEMBER_UNION_CHECK(union_name) template<typename T, typename = std::true_type> struct has_member_union_##union_name : std::false_type {}; template<typename T> struct has_member_union_##union_name< T , std::integral_constant< bool , std::is_union< typename got_type<typename T::union_name>::type >::value > > : std::true_type {} </code>
//Check for member union with given name.
#define CREATE_MEMBER_UNION_CHECK(union_name)               
                                                            
template<typename T, typename = std::true_type>             
struct has_member_union_##union_name : std::false_type {};  
                                                            
template<typename T>                                        
struct has_member_union_##union_name<                       
    T                                                       
    , std::integral_constant<                               
        bool                                                
        , std::is_union<                                    
            typename got_type<typename T::union_name>::type 
        >::value                                            
    >                                                       
> : std::true_type {}

CREATE_MEMBER_ENUM_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for member enum with given name.
#define CREATE_MEMBER_ENUM_CHECK(enum_name)
template<typename T, typename = std::true_type>
struct has_member_enum_##enum_name : std::false_type {};
template<typename T>
struct has_member_enum_##enum_name<
T
, std::integral_constant<
bool
, std::is_enum<
typename got_type<typename T::enum_name>::type
>::value
>
> : std::true_type {}
</code>
<code>//Check for member enum with given name. #define CREATE_MEMBER_ENUM_CHECK(enum_name) template<typename T, typename = std::true_type> struct has_member_enum_##enum_name : std::false_type {}; template<typename T> struct has_member_enum_##enum_name< T , std::integral_constant< bool , std::is_enum< typename got_type<typename T::enum_name>::type >::value > > : std::true_type {} </code>
//Check for member enum with given name.
#define CREATE_MEMBER_ENUM_CHECK(enum_name)                 
                                                            
template<typename T, typename = std::true_type>             
struct has_member_enum_##enum_name : std::false_type {};    
                                                            
template<typename T>                                        
struct has_member_enum_##enum_name<                         
    T                                                       
    , std::integral_constant<                               
        bool                                                
        , std::is_enum<                                     
            typename got_type<typename T::enum_name>::type  
        >::value                                            
    >                                                       
> : std::true_type {}

CREATE_MEMBER_FUNC_CHECK:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Check for function with given name, any signature.
#define CREATE_MEMBER_FUNC_CHECK(func)
template<typename T>
struct has_member_func_##func {
static const bool value
= has_member_##func<T>::value
&& !has_member_var_##func<T>::value
&& !has_member_class_##func<T>::value
&& !has_member_union_##func<T>::value
&& !has_member_enum_##func<T>::value
;
}
</code>
<code>//Check for function with given name, any signature. #define CREATE_MEMBER_FUNC_CHECK(func) template<typename T> struct has_member_func_##func { static const bool value = has_member_##func<T>::value && !has_member_var_##func<T>::value && !has_member_class_##func<T>::value && !has_member_union_##func<T>::value && !has_member_enum_##func<T>::value ; } </code>
//Check for function with given name, any signature.
#define CREATE_MEMBER_FUNC_CHECK(func)          
template<typename T>                            
struct has_member_func_##func {                 
    static const bool value                     
        = has_member_##func<T>::value           
        && !has_member_var_##func<T>::value     
        && !has_member_class_##func<T>::value   
        && !has_member_union_##func<T>::value   
        && !has_member_enum_##func<T>::value    
    ;                                           
}

CREATE_MEMBER_CHECKS:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>//Create all the checks for one member. Does NOT include func sig checks.
#define CREATE_MEMBER_CHECKS(member)
CREATE_MEMBER_CHECK(member);
CREATE_MEMBER_VAR_CHECK(member);
CREATE_MEMBER_CLASS_CHECK(member);
CREATE_MEMBER_UNION_CHECK(member);
CREATE_MEMBER_ENUM_CHECK(member);
CREATE_MEMBER_FUNC_CHECK(member)
</code>
<code>//Create all the checks for one member. Does NOT include func sig checks. #define CREATE_MEMBER_CHECKS(member) CREATE_MEMBER_CHECK(member); CREATE_MEMBER_VAR_CHECK(member); CREATE_MEMBER_CLASS_CHECK(member); CREATE_MEMBER_UNION_CHECK(member); CREATE_MEMBER_ENUM_CHECK(member); CREATE_MEMBER_FUNC_CHECK(member) </code>
//Create all the checks for one member.  Does NOT include func sig checks.
#define CREATE_MEMBER_CHECKS(member)    
CREATE_MEMBER_CHECK(member);            
CREATE_MEMBER_VAR_CHECK(member);        
CREATE_MEMBER_CLASS_CHECK(member);      
CREATE_MEMBER_UNION_CHECK(member);      
CREATE_MEMBER_ENUM_CHECK(member);       
CREATE_MEMBER_FUNC_CHECK(member)

2

Boost.ConceptTraits provides between others some macros to define type traits, as for example BOOST_TT_EXT_DEFINE_HAS_MEMBER(name), which defines a type trait of the form:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>has_member_##name<T>
</code>
<code>has_member_##name<T> </code>
has_member_##name<T>

This gives true if T has a member type named . Note, however, that this won’t detect reference type members.

In you case it will be enough to add in a header file

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x)
</code>
<code>BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x) </code>
BOOST_TT_EXT_DEFINE_HAS_MEMBER_TYPE(x)

and check as follows

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>BOOST_STATIC_ASSERT(has_member_x<P1>::value);
</code>
<code>BOOST_STATIC_ASSERT(has_member_x<P1>::value); </code>
BOOST_STATIC_ASSERT(has_member_x<P1>::value);

The technique used is the same as the one explained on some of the preceding answers.

Unfortunately this library is no more maintained. Now that C++0x will not includes concept, this library together with SFINAE is a perfect replacement to work with most of the concepts.

2

Why don’t you use specialization like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>struct P1 {int x; };
struct P2 {int X; };
template<class P>
bool Check_x(P p) { return true; }
template<>
bool Check_x<P2>(P2 p) { return false; }
</code>
<code>struct P1 {int x; }; struct P2 {int X; }; template<class P> bool Check_x(P p) { return true; } template<> bool Check_x<P2>(P2 p) { return false; } </code>
struct P1 {int x; };
struct P2 {int X; };

template<class P> 
bool Check_x(P p) { return true; }

template<> 
bool Check_x<P2>(P2 p) { return false; }

3

Are the functions (x, X, y, Y) from an abstract base class, or could they be refactored to be so? If so you can use the SUPERSUBCLASS() macro from Modern C++ Design, along with ideas from the answer to this question:

Compile-time type based dispatch

Why don’t you just create template specializations of Check_x ?

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>template<> bool Check_x(P1 p) { return true; }
template<> bool Check_x(P2 p) { return false; }
</code>
<code>template<> bool Check_x(P1 p) { return true; } template<> bool Check_x(P2 p) { return false; } </code>
template<> bool Check_x(P1 p) { return true; }
template<> bool Check_x(P2 p) { return false; }

Heck, when I think of it. If you only have two types, why do you even need templates for this?

1

We can get at compile time: 0 - not_member, 1 - is_object, 2 - is_function for each required class and member – object or function: http://ideone.com/Fjm9u5

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include <iostream>
#include <type_traits>
#define IS_MEMBER(T1, M)
struct {
struct verystrangename1 { bool M; };
template<typename T> struct verystrangename2 : verystrangename1, public T { };
enum return_t { not_member, is_object, is_function };
template<typename T, typename = decltype(verystrangename2<T>::M)> constexpr return_t what_member() { return not_member; }
template<typename T> typename std::enable_if<std::is_member_object_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_object; }
template<typename T> typename std::enable_if<std::is_member_function_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_function; }
constexpr operator return_t() { return what_member<T1>(); }
}
struct t {
int aaa;
float bbb;
void func() {}
};
// Can't be in function
IS_MEMBER(t, aaa) is_aaa_member_of_t;
IS_MEMBER(t, ccc) is_ccc_member_of_t;
IS_MEMBER(t, func) is_func_member_of_t;
// known at compile time
enum { const_is_aaa_member_of_t = (int)is_aaa_member_of_t };
static constexpr int const_is_func_member_of_t = is_func_member_of_t;
int main() {
std::cout << std::boolalpha << "0 - not_member, 1 - is_object, 2 - is_function nn" <<
"is aaa member of t = " << is_aaa_member_of_t << std::endl <<
"is ccc member of t = " << is_ccc_member_of_t << std::endl <<
"is func member of t = " << is_func_member_of_t << std::endl <<
std::endl;
return 0;
}
</code>
<code>#include <iostream> #include <type_traits> #define IS_MEMBER(T1, M) struct { struct verystrangename1 { bool M; }; template<typename T> struct verystrangename2 : verystrangename1, public T { }; enum return_t { not_member, is_object, is_function }; template<typename T, typename = decltype(verystrangename2<T>::M)> constexpr return_t what_member() { return not_member; } template<typename T> typename std::enable_if<std::is_member_object_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_object; } template<typename T> typename std::enable_if<std::is_member_function_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_function; } constexpr operator return_t() { return what_member<T1>(); } } struct t { int aaa; float bbb; void func() {} }; // Can't be in function IS_MEMBER(t, aaa) is_aaa_member_of_t; IS_MEMBER(t, ccc) is_ccc_member_of_t; IS_MEMBER(t, func) is_func_member_of_t; // known at compile time enum { const_is_aaa_member_of_t = (int)is_aaa_member_of_t }; static constexpr int const_is_func_member_of_t = is_func_member_of_t; int main() { std::cout << std::boolalpha << "0 - not_member, 1 - is_object, 2 - is_function nn" << "is aaa member of t = " << is_aaa_member_of_t << std::endl << "is ccc member of t = " << is_ccc_member_of_t << std::endl << "is func member of t = " << is_func_member_of_t << std::endl << std::endl; return 0; } </code>
#include <iostream>
#include <type_traits>

#define IS_MEMBER(T1, M)    
struct {        
    struct verystrangename1 { bool M; };    
    template<typename T> struct verystrangename2 : verystrangename1, public T { }; 
    
    enum return_t { not_member, is_object, is_function }; 
    template<typename T, typename = decltype(verystrangename2<T>::M)> constexpr return_t what_member() { return not_member;  }  
    template<typename T> typename std::enable_if<std::is_member_object_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_object; }   
    template<typename T> typename std::enable_if<std::is_member_function_pointer<decltype(&T::M)>::value, return_t>::type constexpr what_member() { return is_function; }   
    constexpr operator return_t() { return what_member<T1>(); } 
}

struct t {
    int aaa;
    float bbb;
    void func() {}
};

// Can't be in function
IS_MEMBER(t, aaa) is_aaa_member_of_t;
IS_MEMBER(t, ccc) is_ccc_member_of_t;
IS_MEMBER(t, func) is_func_member_of_t;

// known at compile time
enum { const_is_aaa_member_of_t = (int)is_aaa_member_of_t };
static constexpr int const_is_func_member_of_t = is_func_member_of_t;

int main() {        
    std::cout << std::boolalpha << "0 - not_member, 1 - is_object, 2 - is_function nn" <<
        "is aaa member of t = " << is_aaa_member_of_t << std::endl << 
        "is ccc member of t = " << is_ccc_member_of_t << std::endl << 
        "is func member of t = " << is_func_member_of_t << std::endl << 
        std::endl;

    return 0;
}

Result:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>0 - not_member, 1 - is_object, 2 - is_function
is aaa member of t = 1
is ccc member of t = 0
is func member of t = 2
</code>
<code>0 - not_member, 1 - is_object, 2 - is_function is aaa member of t = 1 is ccc member of t = 0 is func member of t = 2 </code>
0 - not_member, 1 - is_object, 2 - is_function 

is aaa member of t = 1
is ccc member of t = 0
is func member of t = 2

For class/struct:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>struct t {
int aaa;
float bbb;
void func() {}
};
</code>
<code>struct t { int aaa; float bbb; void func() {} }; </code>
struct t {
    int aaa;
    float bbb;
    void func() {}
};

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật