【问题标题】:Virtual variadic template method in interface接口中的虚拟可变参数模板方法
【发布时间】:2021-06-04 15:07:41
【问题描述】:

在 C++ 中不能有虚拟模板方法。我想要一个接口和一些实现它的类。例如:

class Logger {
   public:
    template<typename... Args>
       virtual void Error(const std::string& message, Args... args) const = 0;
    
};

class ConsoleLogger : public Logger {    
   public:
   template<typename... Args>
         void Error(const std::string& message, Args... args) const{} 
};

有什么解决办法吗?我还是想用这个界面。

【问题讨论】:

  • 你考虑过CRTP吗?
  • 您可以使用奇怪重复的模板模式或 pimpl 代替继承。
  • 我没有听说过 CRTP。谢谢各位,我会研究的。
  • @LiviuDorobantu 下面是一个使用 CRTP 的记录器的快速实现:gcc.godbolt.org/z/KndG73sYf
  • 再次感谢您,弗兰克!

标签: c++ templates interface variadic


【解决方案1】:

尽管“更喜欢组合而不是继承”往往被盲目地模仿,但它确实在这里派上了用场。

class LoggerImpl {
public:
  virtual ~LoggerImpl() {}
  virtual void dispatch(const std::string& message, std::vector<std::string> args) = 0;
};

class Logger {
   std::unique_ptr<LoggerImpl> _impl;
   public:
    Logger(std::unique_ptr<LoggerImpl> impl) : _impl(impl) {}
    
    template<typename... Args>
    void Error(const std::string& message, Args... args) const {
      std::vector<std::string> args_as_strings;
      // Make strings from args

      _impl->dispatch(message, std::move(args_as_strings));
    }
};

您实际上如何将 args 传递给 _impl 不一定是向量。这主要是一个实现细节。只要您使用的任何机制都是“虚拟友好的”。它会正常工作的。

【讨论】:

  • 谢谢!我不允许使用向量,因为它可以动态分配。也许我应该使用一个数组。
  • @LiviuDorobantu 使用数组是个坏主意。 Args... args 是一个开放式列表,所以它应该被打包到一个开放式容器中。这种限制确实改变了一些事情,CRTP 解决方案更适合这种情况。
  • 好的,非常感谢弗兰克!我不知道 CRTP 是什么。我会研究它。再次感谢!
  • @LiviuDorobantu 最后一点:“我不允许使用向量,因为它可以动态分配”正如您所知,只需将字符串作为参数之一传递就可以动态分配内存。您可能希望签名为Args&amp;&amp;... args
  • 是的,你是对的。我应该使用 Args&&。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
相关资源
最近更新 更多