使用组合而不是继承的方法转发(使用C+;+;特征) 我想使用构图,并用C++的能力为每一个可能的过载(除了,const,易失性)编写好的转发方法。

使用组合而不是继承的方法转发(使用C+;+;特征) 我想使用构图,并用C++的能力为每一个可能的过载(除了,const,易失性)编写好的转发方法。,c++,templates,inheritance,metaprogramming,composition,C++,Templates,Inheritance,Metaprogramming,Composition,其思想是使用traits来确定一个方法是否被声明为{noexcept/const/volatile/etc},并相应地进行操作 以下是我想要实现的一个例子: struct User{ UsedObject& obj; User(UsedObject& obj) : obj(obj) {} FORWARD_METHOD(obj, get); //here is where the forwarding happens }; struct Used

其思想是使用traits来确定一个方法是否被声明为{noexcept/const/volatile/etc},并相应地进行操作

以下是我想要实现的一个例子:

struct User{    
    UsedObject& obj;
    User(UsedObject& obj) : obj(obj) {}

    FORWARD_METHOD(obj, get); //here is where the forwarding happens
};

struct UsedObject{
    string m{"Hello\n"};

    string& get(double d){
        cout << "\tUsed :const not called...\n";
        return m;
    }
    const string& get(double d) const{
        cout << "\tUsed :const called...\n";
        return m;
    }
};
struct User{
UsedObject&obj;
用户(UsedObject&obj):obj(obj){}
FORWARD_METHOD(obj,get);//这里是进行转发的地方
};
结构UsedObject{
字符串m{“Hello\n”};
string&get(双d){

让我们从解决方案开始,逐一解释

#define FORWARDING_MEMBER_FUNCTION(Inner, inner, function, qualifiers) \
    template< \
        typename... Args, \
        typename return_type = decltype(std::declval<Inner qualifiers>().function(std::declval<Args &&>()...)) \
    > \
    constexpr decltype(auto) function(Args && ... args) qualifiers noexcept( \
        noexcept(std::declval<Inner qualifiers>().function(std::forward<Args>(args)...)) and \
        ( \
            std::is_reference<return_type>::value or \
            std::is_nothrow_move_constructible<return_type>::value \
        ) \
    ) { \
        return static_cast<Inner qualifiers>(inner).function(std::forward<Args>(args)...); \
    }

#define FORWARDING_MEMBER_FUNCTIONS_CV(Inner, inner, function, reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, const reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, volatile reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, const volatile reference)

#define FORWARDING_MEMBER_FUNCTIONS(Inner, inner, function) \
    FORWARDING_MEMBER_FUNCTIONS_CV(Inner, inner, function, &) \
    FORWARDING_MEMBER_FUNCTIONS_CV(Inner, inner, function, &&)
这具有以下优点:

  • 可读性
  • 更快的编译时间
  • 调试构建中更快的代码(无需内联)
  • 不使用constexpr递归深度
  • 不使用模板实例化深度
  • 使用按值返回不可移动的类型
  • 与转发给构造函数一起工作

谢谢你的回答!我学到了很多元编程的知识。我们可以这样使用吗?
转发成员函数(std::detacy::type,internal,function)
和成员指针:
转发成员函数(std::detacy::type,*ptr,function)什么阻止C++提供相同的语法<代码>使用内联?函数;< /COD> >构图?@ JuleNeNy]可以更改宏以接受参数的类型。缺点是,在调用前传TypMeNeMyStk函数之前,必须先声明变量声明,而如果指定了显式类型,则必须先声明变量。当然,这个限制是不存在的。哪一个更好的是由你来决定的。但是,由于引用限定符,你可能不想用指针来使用它。没有什么能阻止C++使用使用语法来转发成员的函数,除非你必须说服委员会接受它。@ DavidStone从BITBUC中复制代码。ket repo和编译over at会导致编译错误,除非您注释掉大部分转发成员函数(仅供参考的函数除外)…在webcompiler.cloudapp.net上为msvc编译对我来说更加神秘。我无法理解从第二个noexcept开始的部分的用法…以及从第二个noexcept开始的部分的用法s_reference..or is_nothrow..@xerion:Visual Studio在其C++14一致性方面仍然远远落后。示例代码依赖于constexpr、成员函数的引用限定符和普通函数的自动返回类型推断,直到Visual Studio 2015(尚未发布)才支持这些。我不知道编译时使用的是什么版本的gcc ideone。在C++14中使用任何东西时,最好使用最新版本的clang,或者至少是最新版本的gcc。
#define FORWARDING_MEMBER_FUNCTION(Inner, inner, function, qualifiers) \
    template< \
        typename... Args, \
        typename return_type = decltype(std::declval<Inner qualifiers>().function(std::declval<Args &&>()...)) \
    > \
    constexpr decltype(auto) function(Args && ... args) qualifiers noexcept( \
        noexcept(std::declval<Inner qualifiers>().function(std::forward<Args>(args)...)) and \
        ( \
            std::is_reference<return_type>::value or \
            std::is_nothrow_move_constructible<return_type>::value \
        ) \
    ) { \
        return static_cast<Inner qualifiers>(inner).function(std::forward<Args>(args)...); \
    }

#define FORWARDING_MEMBER_FUNCTIONS_CV(Inner, inner, function, reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, const reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, volatile reference) \
    FORWARDING_MEMBER_FUNCTION(Inner, inner, function, const volatile reference)

#define FORWARDING_MEMBER_FUNCTIONS(Inner, inner, function) \
    FORWARDING_MEMBER_FUNCTIONS_CV(Inner, inner, function, &) \
    FORWARDING_MEMBER_FUNCTIONS_CV(Inner, inner, function, &&)
struct Outer : private Inner {
    using Inner::f;
};