C++11 如何代理只有其名称和父类的类函数

C++11 how to proxy class function having only its name and parent class?

本文关键字:父类 类函数 何代理 代理 C++11      更新时间:2023-10-16

我想知道是否可以使用 boost::mpl/预处理器或一些 noce C++11 功能从类类型和函数名称创建函数代理。

假设我们有:

  inline void set_email(const ::std::string& value);
  inline void set_email(const char* value);

课堂内电子邮件。我们知道它有set_email函数,我们想创建一个带有 API 的 prox 类,例如

PROXY(Email, set_email, MyEmail)
Email * email = new Email();
MyEmail * myEmail = new MyEmail(email);

并有能力调用set_email过载中的任何一个。是否有可能以及如何创建这样的类来代理不知道类型(仅名称)的任意数量的重载函数?

这个怎么样:

proxy_macro.hpp

#include <type_traits>
#include <utility>
#define PROXY(proxified, member_function, proxy_name)                                                                           
  class proxy_name                                                                                                              
  {                                                                                                                             
  private:                                                                                                                      
    proxified & ref_;                                                                                                           
                                                                                                                                
  public:                                                                                                                       
    proxy_name(proxified &ref)                                                                                                  
      : ref_(ref)                                                                                                               
      {                                                                                                                         
      }                                                                                                                         
                                                                                                                                
    /* general version */                                                                                                       
    template<typename ... Args>                                                                                                 
    auto member_function(Args&& ... args)                                                                                       
    -> typename std::enable_if<!std::is_void<decltype(ref_.member_function(std::forward<Args>(args)...))>::value,               
                               decltype(ref_.member_function(std::forward<Args>(args)...))>::type                               
      {                                                                                                                         
        return (ref_.member_function(std::forward<Args>(args)...));                                                             
      }                                                                                                                         
                                                                                                                                
    /* void return type version */                                                                                              
    template<typename ... Args>                                                                                                 
    auto member_function(Args&& ... args)                                                                                       
    -> typename std::enable_if<std::is_void<decltype(ref_.member_function(std::forward<Args>(args)...))>::value,                
                               void>::type                                                                                      
      {                                                                                                                         
        ref_.member_function(std::forward<Args>(args)...);                                                                      
      }                                                                                                                         
                                                                                                                                
  };

这在g++ 4.7上编译并对我来说工作正常:

#include "proxy_macro.hpp"
#include <iostream>
#include <string>
class   Email
{
public:  
  void set_email(const ::std::string& value)
  {
    std::cout << value << std::endl;
  }
  void set_email(const char* value)
  {
    std::cout << value << std::endl;
  }
  int   set_email()
  {
    return (42);
  }
};
PROXY(Email, set_email, MyEmail)
int main(void)
{
  Email   mail;
  MyEmail my_mail(mail);
  std::string str = "test string";
  const char * ptr = "test char pointer";
  my_mail.set_email(str);
  my_mail.set_email(ptr);
  std::cout << "test return: " << my_mail.set_email() << std::endl;
  return (0);
}

编辑(由于评论而缩小版本)

proxy_macro.hpp

#include <type_traits>
#include <utility>
#define PROXY(proxified, member_function, proxy_name)                
  class proxy_name                                                   
  {                                                                  
  private:                                                           
    proxified & ref_;                                                
                                                                     
  public:                                                            
    proxy_name(proxified &ref)                                       
      : ref_(ref)                                                    
      {                                                              
      }                                                              
                                                                     
    template<typename ... Args>                                      
    auto member_function(Args&& ... args)                            
    -> decltype(ref_.member_function(std::forward<Args>(args)...))   
      {                                                              
        return (ref_.member_function(std::forward<Args>(args)...));  
      }                                                              
  };