通过使用模板特化的 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 成员变量但无济于事。
欢迎任何建议,但我希望以下内容保持不变:
void doOperation()
和 wildlyDifferentOperation()
应该保持 const
- 我希望能够在
doOperation()
和 wildlyDifferentOperation()
中将局部变量创建为 T a
并将它们传递给一个单独的方法,如果它们是容器,则在该方法中调整它们的大小。为了使事情更简单,我知道我将得到一个 double
或一个容器,但我不想对容器的模板参数施加任何限制(即接受 std::vector、std::vector 等等)
- 我需要能够使用相同的功能来调整来自其他子 class 的容器的大小,这些子 class 派生自基础 class。
如果有一个更简洁的解决方案不需要模板专业化,那也是可以接受的。但是,它应该与符合 C++14 标准的编译器一起使用。
将 base::resize
设为 static
或 const
。在不知道你在这里要做什么的语义的情况下,我猜 const
.
我想创建 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 成员变量但无济于事。
欢迎任何建议,但我希望以下内容保持不变:
void doOperation()
和wildlyDifferentOperation()
应该保持const
- 我希望能够在
doOperation()
和wildlyDifferentOperation()
中将局部变量创建为T a
并将它们传递给一个单独的方法,如果它们是容器,则在该方法中调整它们的大小。为了使事情更简单,我知道我将得到一个double
或一个容器,但我不想对容器的模板参数施加任何限制(即接受 std::vector、std::vector 等等) - 我需要能够使用相同的功能来调整来自其他子 class 的容器的大小,这些子 class 派生自基础 class。
如果有一个更简洁的解决方案不需要模板专业化,那也是可以接受的。但是,它应该与符合 C++14 标准的编译器一起使用。
将 base::resize
设为 static
或 const
。在不知道你在这里要做什么的语义的情况下,我猜 const
.