【问题标题】:How to make the following piece of code work by using template or inheritance? [closed]如何使用模板或继承使以下代码工作? [关闭]
【发布时间】:2016-10-22 04:14:07
【问题描述】:

我的问题是关于如何定义成员函数 f1 以使代码工作

#include <iostream>
struct func2{
    int a=3;

    template<typename T1, typename T2, typename T3>           
        void f1(T1 _t1, T2 _t2, T3 _t3){
            std::cout<<a<<"\t"<<_t1<<"\t"<<_t2<<"\t"<<_t3<<std::endl;
        }


    template<typename F1, typename T1, typename T2, typename T3>
        void f2(F1 _f1, T1 _t1, T2 _t2, T3 _t3){
            _f1(_t1, _t2, _t3);
            _f1(_t2, _t1, _t3);
            _f1(_t3, _t2, _t1);
        }

    void f3(){
        int a =1; 
        double b = 2.0;
        std::string c = "hello";
        f2(f1,a,b,c);
    };
};

int main(){       
    func2().f3(); 
}

或者,也许我还需要更改 f2F1。但是,要求保持 f3 原样,因为我可以稍后使用 f2(f1_another,a,b,c),而不是移动 f1f2 脱离了 func2,因为它们依赖于 a。该代码只是我现在面临的问题的一个简单模型。欢迎任何建议或参考。非常感谢。

【问题讨论】:

  • f2([this](auto&amp;&amp;... t){ f1(decltype(t)(t)...); },a,b,c);
  • 添加std::forward不是更好吗?但不确定语法:std::forward&lt;decltype(t)&gt;(t)...
  • 虽然您无法捕获多个重载(当然没有 lambda),但您可以将 std::any 或 ... 作为参数,或者传入排列。

标签: c++ templates c++11 inheritance c++14


【解决方案1】:

这个怎么样?

#include <iostream>

struct func2{
    int a=3;

    struct f1
    {
        const func2* m_this;
        f1(const func2* this_)
        : m_this( this_ )
        {
        }
        template<typename T1, typename T2, typename T3>           
        void operator()(T1 _t1, T2 _t2, T3 _t3){
            std::cout<<m_this->a<<"\t"<<_t1<<"\t"<<_t2<<"\t"<<_t3<<std::endl;
        }
    };

    template<typename F1, typename T1, typename T2, typename T3>
    void f2(F1 _f1, T1 _t1, T2 _t2, T3 _t3){
        _f1(_t1, _t2, _t3);
        _f1(_t2, _t1, _t3);
        _f1(_t3, _t2, _t1);
    }

    void f3(){
        int a =1; 
        double b = 2.0;
        std::string c = "hello";
        f2(f1(this),a,b,c);// The goal is to get flexibility by modifying this line
    };
};

int main(){       
    func2().f3(); 
}

另一种方法是包装模板化的成员函数并传递包装器模板:

#include <iostream>

struct func2{
    int a=3;

    template<typename T1, typename T2, typename T3>           
    void f1(T1 _t1, T2 _t2, T3 _t3){
        std::cout<<a<<"\t"<<_t1<<"\t"<<_t2<<"\t"<<_t3<<std::endl;
    }

    template<typename T1, typename T2, typename T3>
    struct f1wrap
    {
        static constexpr decltype(&func2::f1<T1, T2, T3>) value = &func2::f1<T1, T2, T3>;
    };

    template<template<typename, typename, typename> typename F1, typename T1, typename T2, typename T3>
        void f2(T1 _t1, T2 _t2, T3 _t3){
            (this->*(F1<T1, T2, T3>::value))(_t1, _t2, _t3);
            (this->*(F1<T2, T1, T3>::value))(_t2, _t1, _t3);
            (this->*(F1<T3, T2, T1>::value))(_t3, _t2, _t1);
        }

    void f3(){
        int a =1; 
        double b = 2.0;
        std::string c = "hello";
        f2<f1wrap>(a,b,c);// The goal is to get flexibility by modifying this line
    };
};

int main(){       
    func2().f3(); 
}

如果您广泛使用这种无函数方法,您可能会创建一个宏来从 f1 创建 f1wrap(利用模板参数包)。

【讨论】:

  • 让我知道它是否符合条件。如果不符合条件,我会删除它。
  • 第一种方法是我的想法。但是,我不喜欢它,因为有很多常见的变量,比如 a。我更喜欢第二种方式,尽管我们需要为不同的函数(如 f1)创建许多包装器。谢谢。
  • 好吧,我建议使用宏从 f1 生成 f1wrap(用于任意参数计数)。因为它是一个结构体,所以你不需要把它放在 func2 范围内,你也可以把它放在 f3() 的本地范围内。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 2012-08-31
  • 2014-03-13
  • 1970-01-01
  • 2015-04-18
  • 2023-03-07
相关资源
最近更新 更多