通过使用模板特化的 base class 在 const 方法中调整本地容器的大小

Resizing local containers in const method through base class with template specialisations

我想创建 class 的实例,并根据类型提供调整大小的功能,该功能仅适用于提供此类功能的容器(为简单起见,假设它只是一个向量) .调整大小是在基础 class 中完成的,因为我有几个具有共同基础但都需要相同功能的 classes。

下面的代码演示了当前的问题

#include <iostream>
#include <vector>

class base {
  public:
    template<typename T>
    void resize(T &var, T &resizer) {
      var.resize(resizer.size());
      std::cout << "resized a vector" << std::endl;
    }

    void resize(double &var, double &resizer) {
      std::cout << "just a double, no resizing done" << std::endl;
    }
};

template<typename T>
class child1 : public base {
  public:
    void doOperation() const {
      T a, b;
      // assume here that b has actually a different size from a
      this->resize(a, b);
    }
};

template<typename T>
class child2 : public base {
  public:
    void wildlyDifferentOperation() const {
      T c, d;
      // assume here that d has actually a different size from c
      this->resize(c, d);
    }
};

int main() {
  child1<std::vector<double>> obj1;
  obj1.doOperation();

  child2<std::vector<int>> obj2;
  obj2.wildlyDifferentOperation();

  child1<double> obj3;
  obj3.doOperation();
  return 0;
}

如此处所示,我使用模板特化来捕获无法调整大小的类型(而且我知道它始终是双精度类型)并且我对可以调整大小的容器使用模板化版本,因为我不知道提前知道我实际需要哪些类型(即可能是 std::vector<int>std::vector<double> 等...)。

当然,如果我从 doOperation() 方法中删除 const,那么代码会按预期工作,但是对于 const,我会收到一条错误消息 error: passing ‘const child1<std::vector<double> >’ as ‘this’ argument discards qualifiers [-fpermissive],这并不奇怪(并且我收到了关于 child2 和 wildlyDifferentOperation()) 的类似消息。

我现在的问题是如何使用上面的代码使其工作?我虽然可以 const_cast this->resize 中的参数或使用 mutable 然后将 T a 声明为 class 成员变量但无济于事。 欢迎任何建议,但我希望以下内容保持不变:

  1. void doOperation()wildlyDifferentOperation() 应该保持 const
  2. 我希望能够在 doOperation()wildlyDifferentOperation() 中将局部变量创建为 T a 并将它们传递给一个单独的方法,如果它们是容器,则在该方法中调整它们的大小。为了使事情更简单,我知道我将得到一个 double 或一个容器,但我不想对容器的模板参数施加任何限制(即接受 std::vector、std::vector 等等)
  3. 我需要能够使用相同的功能来调整来自其他子 class 的容器的大小,这些子 class 派生自基础 class。

如果有一个更简洁的解决方案不需要模板专业化,那也是可以接受的。但是,它应该与符合 C++14 标准的编译器一起使用。

base::resize 设为 staticconst。在不知道你在这里要做什么的语义的情况下,我猜 const.