模板函数中的 `std::remove` 导致 `vector.begin()` 成为 `const` 的问题
`std::remove` in template function causing problems with `vector.begin()` being `const`
错误信息:
“二进制‘==’:未找到采用 'const _Ty' 类型的左手操作数的运算符(或没有可接受的转换)”
错误似乎是因为我给 std::remove
第一个参数一个 const
值,但我不明白 v.begin()
不可修改会如何导致问题,也不是为什么只有在模板化向量类型而不是已知类型向量时才会出现此错误。
模板函数:
// Erases a every element of a certain value from a vector
template <typename T>
std::vector<T> eraseElement(std::vector<T> v, T elem)
{
typename std::vector<T>::iterator newEnd = std::remove(v.begin(), v.end(), elem);
v.erase(newEnd, v.end());
return v;
}
我调用模板函数的方式示例:
struct exampleStruct
{
int x;
}
std::vector<exampleStruct> v;
exampleStruct elem;
elem.x = 2451;
v.push_back(elem);
v = eraseElement(v, elem);
The error message: "binary '==': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion)"
The error seems to be because I'm giving std::remove a const value for the first argument
可能不会。该错误是因为您可能使用的 T
不是相等可比较的(换句话说,没有相等运算符 - 这是二进制 operator==
- 会接受操作数)。 Constness 应该不是问题,因为相等可比较类型应该接受 const 参数进行比较。
exampleStruct
特别是不相等可比较。解决问题的一种方法是使它具有可比性。您可以通过为类型定义二进制 operator==
来做到这一点。我推荐以下方法:
struct exampleStruct
{
int x;
friend auto operator<=>(const exampleStruct&, const exampleStruct&) = default;
};
另一种解决问题的方法是不使用std::remove
,而是使用std::remove_if
。这样你就可以提供条件来删除不需要比较元素是否相等的元素。
nor why this error only occurs if the type of the vector is templated, as opposed to a known type vector.
我对此深表怀疑。 exampleStruct
仍然是 non-comparable 无论 eraseElement
是否是模板。
nor why this error only occurs if the type of the vector is templated, as opposed to a known type vector.
它 also occurs 如果您手动替换 exampleStruct
。
std::vector<exampleStruct> eraseElement(std::vector<exampleStruct> v, exampleStruct elem)
{
auto newEnd = std::remove(v.begin(), v.end(), elem);
v.erase(newEnd, v.end());
return v;
}
那是因为 exampleStruct
没有 operator==
。你可能想要像
这样的东西
bool operator==(const exampleStruct & lhs, const exampleStruct & rhs)
{
return lhs.x == rhs.x;
}
或使用 C++20 实现
struct exampleStruct
{
int x;
friend bool operator==(const exampleStruct &, const exampleStruct &) = default;
};
错误信息: “二进制‘==’:未找到采用 'const _Ty' 类型的左手操作数的运算符(或没有可接受的转换)”
错误似乎是因为我给 std::remove
第一个参数一个 const
值,但我不明白 v.begin()
不可修改会如何导致问题,也不是为什么只有在模板化向量类型而不是已知类型向量时才会出现此错误。
模板函数:
// Erases a every element of a certain value from a vector
template <typename T>
std::vector<T> eraseElement(std::vector<T> v, T elem)
{
typename std::vector<T>::iterator newEnd = std::remove(v.begin(), v.end(), elem);
v.erase(newEnd, v.end());
return v;
}
我调用模板函数的方式示例:
struct exampleStruct
{
int x;
}
std::vector<exampleStruct> v;
exampleStruct elem;
elem.x = 2451;
v.push_back(elem);
v = eraseElement(v, elem);
The error message: "binary '==': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion)"
The error seems to be because I'm giving std::remove a const value for the first argument
可能不会。该错误是因为您可能使用的 T
不是相等可比较的(换句话说,没有相等运算符 - 这是二进制 operator==
- 会接受操作数)。 Constness 应该不是问题,因为相等可比较类型应该接受 const 参数进行比较。
exampleStruct
特别是不相等可比较。解决问题的一种方法是使它具有可比性。您可以通过为类型定义二进制 operator==
来做到这一点。我推荐以下方法:
struct exampleStruct
{
int x;
friend auto operator<=>(const exampleStruct&, const exampleStruct&) = default;
};
另一种解决问题的方法是不使用std::remove
,而是使用std::remove_if
。这样你就可以提供条件来删除不需要比较元素是否相等的元素。
nor why this error only occurs if the type of the vector is templated, as opposed to a known type vector.
我对此深表怀疑。 exampleStruct
仍然是 non-comparable 无论 eraseElement
是否是模板。
nor why this error only occurs if the type of the vector is templated, as opposed to a known type vector.
它 also occurs 如果您手动替换 exampleStruct
。
std::vector<exampleStruct> eraseElement(std::vector<exampleStruct> v, exampleStruct elem)
{
auto newEnd = std::remove(v.begin(), v.end(), elem);
v.erase(newEnd, v.end());
return v;
}
那是因为 exampleStruct
没有 operator==
。你可能想要像
bool operator==(const exampleStruct & lhs, const exampleStruct & rhs)
{
return lhs.x == rhs.x;
}
或使用 C++20 实现
struct exampleStruct
{
int x;
friend bool operator==(const exampleStruct &, const exampleStruct &) = default;
};