我有3节课.它是最简单的形式,看起来像,
class tree
{
public:
tree_node* find_node(const std::string& text) {
return factory.find(text);
}
private:
tree_node_factory factory;
}
class tree_node
{
public:
tree_node(const std::string& text) : text_(text) {}
const std::string& text() const {
return text_;
}
void set_parent(const tree_node* new_parent);
private:
std::string text_;
}
class tree_node_factory
{
public:
tree_node* find(const std::string& text);
private:
std::vector<tree_node*> allocated_nodes;
}
Run Code Online (Sandbox Code Playgroud)
我不想让用户tree修改tree_node像方法返回的方法find_node.所以我改变了,find_node并且tree_node_factory::find,
const tree_node* find_node(const std::string& text) const {
return factory.find(text);
}
const tree_node* find(const std::string& …Run Code Online (Sandbox Code Playgroud) 好吧,我现在正在重构我很久以前制作的一个课程.该类是容器类型.
许多函数可以利用类结构的优点,因此实现为成员函数.然而现在它似乎是很多看似"相同"的功能,即"查找"功能:
iterator find(ITEM)
const_iterator find(ITEM) const;
iterator find_if(ITEM, PRED)
const_iterator find_if(ITEM, PRED) const;
Run Code Online (Sandbox Code Playgroud)
4个"函数"来描述几乎相同(并且每个版本的代码几乎相同).更新课程时这变得非常繁琐,我必须确保每个版本都升级.有没有办法更好地处理这些事情?类CAN中的其他一些函数可能需要2个谓词,这意味着我突然有8个函数需要管理.
我试过调用"常量版本的非常量版本",但这显然不起作用.
那么如何处理这些事情呢?只需咬紧牙关并写下来?
编辑:只是为了通知:我的数据结构类似于"树".每个"对象"包含数据(查找搜索)和带有子树的"列表".find函数在树(和子子树)的所有子树上递归递归. - 就像人们在搜索树时所期望的那样.
由于没有明确的"结束"或"开始"迭代器到这样的树,使用std :: find不会产生正确的功能.
我的问题是由我对另一个问题的回答所启发的:https : //stackoverflow.com/a/56989169/2492801。
如果我有一个真正的非const对象,但调用它的一个const方法,那里面的方法this是const当然的。如果我const_cast放弃其常量性并将其传递给对所指向的对象执行写操作的另一种方法,那this是未定义的行为吗?
如果确实如此,我不会感到惊讶,因为this它确实const在const方法内部。另一方面,对象本身不是对象,const因此通常不禁止写操作。
对我来说,重要的是要知道如何处理我的其他问题中所述的问题。谢谢!
与如何删除相似的const和非const成员函数之间的代码重复类似?,我想删除几乎相同的成员函数之间的代码重复,除了ref限定符。
假设我有一个类似这样的课程:
class MyStringBuilder
{
std::string member;
public:
// Other functions
std::string create() const& {
// Some work
std::string result = member;
// More work
return result;
}
std::string create() && {
// Some work
std::string result = std::move(member);
// More work
return result;
}
};
Run Code Online (Sandbox Code Playgroud)
我们想对一个构建器对象执行此操作并非不可想象,因为如果使用完成,它将保存一个副本MyStringBuilder。
除了使用成员的位置外,const&版本和&&版本之间的代码相同。这两个函数之间的唯一区别是,只要引用了该&&版本std::move的任何成员,该版本就可以。
如何避免此代码重复?
在下面的类中,wrapper获取指向任意const方法的指针,并返回对const已删除的方法的调用结果.这可以用来生成相应的非const方法......
struct C {
int x[10];
int const& get(int i) const { return x[i]; }
int const& getr(int const& i) const { return x[i]; }
template<typename T, typename... Ts>
auto& wrapper(T const& (C::*f)(Ts...) const, Ts... args) {
return const_cast<T&>((this->*f)(args...));
}
int& get(int i) { return wrapper(&C::get, i); }
int& getr(int const& i) { return wrapper(&C::getr, i); }
};
Run Code Online (Sandbox Code Playgroud)
几乎.
问题是最终方法getr()无法编译,因为传递给的参数列表wrapper()并不意味着传递引用.当我们进入内部时wrapper(),编译器正在寻找一个按值传递的版本getr().
这有诀窍吗?
我想了解const_cast。
在下面的示例中,items_是一个私有成员变量。
方法getItems()是一种const方法,这意味着它不能修改成员变量items_。
getItems()返回一个const vector引用,这意味着您不能修改成员变量items_。
我的问题是,const_cast在这里有必要吗?我不这样认为,因为我不需要放弃常数性?
#include <iostream>
class test {
std::vector<Item> items_;
public:
const std::vector<Item>& getItems() const;
};
const std::vector<mv::Item>& mv::Workloads::getItems() const
{
return const_cast<std::vector<Item>&>(items_);
}
Run Code Online (Sandbox Code Playgroud) 我有一个泛型Matrix类,我有两个版本operator(),一个const方法返回索引的const引用,一个非const方法返回索引的非const引用(允许我更改它.
我试图通过使用const_cast并调用const版本来使用非const版本,但由于某种原因它不起作用:
template<typename T>
class Matrix
{
std::vector<T> _matrix;
unsigned int _rows;
unsigned int _cols;
public:
const T& operator()(unsigned int row, unsigned int col) const
{
return _matrix[col + (_cols * row)];
}
T& operator()(unsigned int row, unsigned int col)
{
return const_cast<T&>(static_cast<const Matrix*> (*this).operator(row, col));
}
};
Run Code Online (Sandbox Code Playgroud)
它不允许我在最后一行向操作符添加(row,col).有任何想法吗?
我收到以下错误:
Conversion loses qualifiers
Run Code Online (Sandbox Code Playgroud)
尝试在没有代码重复的情况下实现索引运算符时(我将显示代码段):
Point* BufferedList::indexTemp(size_t idx)
{
if (idx >= size) return nullptr;
return &arr[idx];
}
const Point* BufferedList::operator [](size_t idx) const
{
return indexTemp(idx);
}
Point* BufferedList::operator [](size_t idx)
{
return indexTemp(idx);
}
Run Code Online (Sandbox Code Playgroud)
但是,以下有效(这不使用辅助函数indexTemp,它是代码重复):
const Point* BufferedList::operator [](size_t idx) const
{
if (idx >= size) return nullptr;
return &arr[idx];
}
Point* BufferedList::operator [](size_t idx)
{
if (idx >= size) return nullptr;
return &arr[idx];
}
Run Code Online (Sandbox Code Playgroud)
我真的需要两个用于索引的函数(一个返回Point*,另一个返回const Point*)?