【问题标题】:How to create an interface for a class that has templated functions?如何为具有模板化函数的类创建接口?
【发布时间】:2021-08-14 03:30:51
【问题描述】:

我有一个如下所示的课程:

class A
{
  template<typename T>
  T readValue(std::string name) { 
    return member.readValue<T>(name);
  }
 private:
  MemberType member_;
}

我有另一个依赖于它的类,我需要用这个类的模拟版本注入那个类。所以我试图为这个类创建一个接口,我可以依赖它并用一个模拟对象来实现。

问题是我无法使用这样的模板函数创建接口:

class IA
{
  template<typename T>
  virtual T readValue(std::string name) = 0;
}

class A : public IA
{
 public:
  template<typename T>
  virtual T readValue(std::string name)
  {
    return member_.readValue<T>(name);
  }
 private:
  MemberType member_;
}

我如何干净地做到这一点?对于如何做到这一点,所有现有的答案似乎都需要从类中提取简单的接口。

【问题讨论】:

    标签: c++ templates dependency-injection interface


    【解决方案1】:

    模板化的函数是虚拟的没有意义。直接使用模板而不是:

    struct IA { /* ... */ };
    struct A : IA { /* ... */ };
    
    void foo(IA const&);
    

    struct A { /* ... */ };
    
    template <class IA>
    void foo(IA const&);
    

    【讨论】:

    • 如何确保只接受实现接口的类作为模板参数?
    • @AlexisWinters 看看 C++20 concepts。在 C++20 之前,通常的做法是记录所需的接口并依赖于编译时的鸭子类型。无论如何,这就是 STL 所做的。
    • 还有:大量使用static_assert
    • @MooingDuck 你如何使用static_assert 来验证成员函数的存在?可以使用 SFINAE。
    • @AyxanHaqverdili 不,你肯定想在这里避免 SFINAE。 SFINAE 擅长从一组重载中删除方法,但如果在任何其他上下文中使用,只会导致令人困惑的错误消息。类和方法中的static_assert 提供清晰易读的编译器错误消息。 static_assert(std::is_same_v&lt;char, decltype(parameter.readValue&lt;char&gt;("")), "parameter is missing a valid readValue member");
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    相关资源
    最近更新 更多