【问题标题】:multiple static interfaces with implementation-dependent type of member function具有依赖于实现类型的成员函数的多个静态接口
【发布时间】:2019-10-17 18:48:59
【问题描述】:

我有两个接口要与 CRTP 一起用于静态多态性。其中之一包含一个函数,其签名中的类型依赖于实现。

这个问题看起来像here 没有解决的问题。我想出的解决方案包括定义类型的附加模板结构。然后,此模板专门用于实现避免“不完整类型的无效使用”错误。

这是我的代码

#include <iostream>
#include <memory>

template<class impl1>
struct Interface1 {
    double foo() { return static_cast<impl1*>(this)->fooimpl();}
};

template<class impl1, class impl2>
struct typeHelp;

template<class impl1, class impl2>
struct Interface2 {
    void bar(typename typeHelp<impl1,impl2>::type value) {
        static_cast<impl2*>(this)->barimpl(value);
    }
};

//Implementation2 pre declaration
template<class impl1>
struct Implementation2;

//Partial specialization of templated typeHelp
template<class impl1>
struct typeHelp<impl1, Implementation2<impl1>> {
    using type = int;
};

//Implementation2
template<class impl1>
struct Implementation2 : public Interface2<impl1, Implementation2<impl1>> {
    std::shared_ptr<Interface1<impl1>> imp1;
    void barimpl(typename typeHelp<impl1,Implementation2>::type value) {
        std::cout << imp1->foo() << " " << value << std::endl;
    }
};

//Implementation1
struct Implementation1 : public Interface1<Implementation1> {
    double fooimpl() {return 0.;}
};

int main()
{
    Implementation2<Implementation1> obj;
    obj.imp1 = std::make_shared<Implementation1>();
    obj.bar(4);
}

我不喜欢这段代码中的 Interface2 和 typeHelp 依赖于模板参数 impl1。这适用于我的特殊情况,其中 Implementation2 是相对于 impl1 进行模板化的,但如果 Implementation2 不是,则不会。我想知道这个问题是否有更通用和更优雅的解决方案。

【问题讨论】:

    标签: c++ crtp interface-implementation static-polymorphism


    【解决方案1】:

    我的错;多一点搜索,我就会找到答案。在这个link 上,Andy G 指出可以使用模板类来专门化类模板。结果比以前更干净了

    #include <iostream>
    #include <memory>
    
    //Interface1.hpp
    template<class impl1>
    struct Interface1 {
        double foo() { return static_cast<impl1*>(this)->fooimpl();}
    };
    
    //Interface2.hpp
    template<class impl2>
    struct typeHelp;
    
    template<class impl2>
    struct Interface2 {
        void bar(typename typeHelp<impl2>::type value) {
            static_cast<impl2*>(this)->barimpl(value);
        }
    };
    
    //Implementation2.hpp
    template<class impl1>
    struct Implementation2;
    
    //specialization of typeHelp with templated class
    template<class impl1>
    struct typeHelp<Implementation2<impl1>> {
        using type = int;
    };
    
    //Actual implementation of Implementation2
    template<class impl1>
    struct Implementation2 : public Interface2<Implementation2<impl1>> {
        std::shared_ptr<Interface1<impl1>> imp1;
        void barimpl(typename typeHelp<Implementation2<impl1>>::type value) {
            std::cout << imp1->foo() << " " << value << std::endl;
        }
    };
    
    //Implementation1.hpp
    struct Implementation1 : public Interface1<Implementation1> {
        double fooimpl() {return 0.;}
    };
    
    //Main.hpp
    int main()
    {
        Implementation2<Implementation1> obj;
        obj.imp1 = std::make_shared<Implementation1>();
        obj.bar(4);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2011-02-17
      • 2015-09-27
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      相关资源
      最近更新 更多