如何使用模板或继承使以下代码工作?

时间:2016-06-20 19:34:00

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

我的问题是如何定义成员函数 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(); 
}

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

1 个答案:

答案 0 :(得分:2)

这个怎么样?:

#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(利用模板参数包)。