How to check if a class has a nested class definition or typedef in C ++ 11?

In my project, I want to implement a template proxy class of some existing larger classes. Existing classes are library classes, so they cannot be changed. In most cases, clients do not know that the objects are instances of a proxy class or a larger class. In some cases, however, customers MUST know the details of the class. Since the proxy class itself is a template class, I do not think that simply overloading functions by the class name can solve this problem. Perhaps I decided to add an internal inner nested class or typedef inside the proxy class, and the client checks to see if this class / typedef exists to get class information. My question is: how to check if a class has a nested class definition or typedef in C ++ 11?

The following codes show an example:

#include <iostream> #include <functional> #include <string> #include <vector> #include <type_traits> typedef std::string CBig1; // use string for demonstration typedef std::string CBig2; // use string for demonstration //class CBig1; // the bigger class 1, codes of which can not be changed //class CBig2; // the bigger class 2, codes of which can not be changed template <typename _Big, typename _Other> class CProxy { public: struct proxy_tag { }; }; // how to implement this ? // the proxy traits class, if defined _T::proxy_tag, the ``type'' will be std::true_type, otherwise the ``type'' will be std::false_type template <typename _T> struct is_proxy { //typedef std::true_type type; //typedef std::false_type type; }; template <typename _T> void ClientHelp(const _T& t, std::false_type) { // process real class std::cerr << "real class" << std::endl; } template <typename _T> void ClientHelp(const _T& t, std::true_type) { // process proxy class std::cerr << "proxy class" << std::endl; } template <typename _T> void Client(const _T& t) { ClientHelp(t, typename is_proxy<_T>::type()); } int main(int argc, char* argv[]) { CBig1 b; CProxy<CBig1, int> p; Client(b); Client(p); return 0; } 

How to implement the is_proxy feature is_proxy ?

+6
source share
2 answers

As a complement to C ++ 03 in C ++ 11, you get decltype :

 template <typename T> auto is_proxy(T const&) -> decltype(T::proxy_tag{}, std::true_type{}) { return std::true_type{}; } std::false_type is_proxy(...) { return std::false_type{}; } 

And your Client implementation becomes:

 template <typename T> void Client(T const& t) { ClientHelp(t, is_proxy(t)); } 

Sweet, right?

+10
source

You can use idiom simplified classification

 template<class T, class R = void> struct enable_if_type { typedef R type; }; template<class T, class Enable = void> struct test : std::false_type {}; template<class T> struct test<T, typename enable_if_type<typename T::is_proxy_tag>::type> : std::true_type {}; template <typename _Big, typename _Other> class CProxy { public: typedef void is_proxy_tag; }; 

So, to make a proxy class, just add this

 typedef void is_proxy_tag; 

and SFINAE in enable_if_type will select the correct true_type / false_type specialization

Note that using boost::mpl::true_ instead of std::true_type etc. makes this solution for C ++ 03.

+16
source

Source: https://habr.com/ru/post/910394/


All Articles