如何重载 << 运算符以使用模板函数将元素添加到向量中? (c++)
How to overload the << operator to add elements to a vector using a template function? (c++)
我正在为学校做一个项目,我的老师希望我们重载“<<”运算符,以便它向向量添加元素。他还希望我们使用模板,以便它可以用于任何类型的元素。
这是我的头文件代码:
template<typename T>
vector<T>& operator<<(vector<T>& v, const T element) {
v.push_back(element);
return v;
}
这就是我正在尝试的 运行:
v1 << "Atlanta" << "Dallas" << "Chicago" << "Boston" << "Denver";
我得到的错误是:
error C2676: binary '<<': 'std::vector<std::string,std::allocator<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
谁能帮我解释为什么这不起作用?我使用的是最新版本的 visual studio 并且我已经将我的文件正确添加到解决方案和所有内容中。当我用 "const string element" 替换 "const T element" 一段时间时,它工作了一点,但是一旦我再次添加实现,它就不起作用了。谢谢指教。
编辑:感谢您的帮助,这是最终为我工作的答案:
template<typename T, typename U>
vector<T>& operator<<(vector<T>& v, const U& element) {
v.push_back(element);
return v;
}
像 "Atlanta"
这样的字符串文字不是 std::string
类型(它们是 char
的数组),但是您的函数需要向量元素类型和运算符右侧参数键入相同的类型。
如果你允许右边的参数类型不同,那么它就可以工作,例如:
template<typename T, typename U>
std::vector<T>& operator<<(std::vector<T>& v, U&& element) {
v.emplace_back(std::forward<U>(element));
return v;
}
请注意,我将参数移动到向量中以避免不必要的深层复制,例如按值传入 std::string
。
编辑: 更改为使用 emplace_back
,如评论中所述
如果向量元素的类型和运算符的参数匹配,则以下内容将编译:
std::vector<const char*> v1;
v1 << "Atlanta" << "Dallas" << "Chicago" << "Boston" << "Denver";
同样使用 std::string
文字也适用于 std::string
s 的向量:
using namespace std::string_literals;
std::vector<std::string> v1;
v1 << "Atlanta"s << "Dallas"s << "Chicago"s << "Boston"s << "Denver"s;
可以通过添加另一个模板将 char
数组直接放入 std::string
元素中:
//this template will accept the const char array and construct a string
template<class T, class S, size_t N>
std::vector<S>& operator<<(std::vector<S>& v, const T(& arr)[N])
{
v.push_back({std::begin(arr), std::end(arr)});
//v.push_back(arr); // would also work for char
return v;
}
当你使用
v1 << "Atlanta" << "Dallas" << "Chicago" << "Boston" << "Denver";
参数 T
未推导为 std::string
。对于"Atlanta"
,推导为‘const char [8]
。其他参数的类型将以类似方式推导。
更改函数,以便从 std::vector
.
推导出元素的类型
template<typename Vector>
Vector& operator<<(Vector& v, typename Vector::value_type const& element) {
v.push_back(element);
return v;
}
添加到,使用完美的参数转发可以更好:
template<typename T, typename U>
std::vector<T>& operator<<(std::vector<T>& v, U&& element) {
v.emplace_back(std::forward<U>(element));
return v;
}
与@emlai 使用 std::move
的解决方案相比,这个解决方案使用完美的参数转发,它可以直接将对象移动到向量中,而不是按值传递它。
编辑: 更改为使用 emplace_back,如评论中所述
我正在为学校做一个项目,我的老师希望我们重载“<<”运算符,以便它向向量添加元素。他还希望我们使用模板,以便它可以用于任何类型的元素。
这是我的头文件代码:
template<typename T>
vector<T>& operator<<(vector<T>& v, const T element) {
v.push_back(element);
return v;
}
这就是我正在尝试的 运行:
v1 << "Atlanta" << "Dallas" << "Chicago" << "Boston" << "Denver";
我得到的错误是:
error C2676: binary '<<': 'std::vector<std::string,std::allocator<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
谁能帮我解释为什么这不起作用?我使用的是最新版本的 visual studio 并且我已经将我的文件正确添加到解决方案和所有内容中。当我用 "const string element" 替换 "const T element" 一段时间时,它工作了一点,但是一旦我再次添加实现,它就不起作用了。谢谢指教。
编辑:感谢您的帮助,这是最终为我工作的答案:
template<typename T, typename U>
vector<T>& operator<<(vector<T>& v, const U& element) {
v.push_back(element);
return v;
}
像 "Atlanta"
这样的字符串文字不是 std::string
类型(它们是 char
的数组),但是您的函数需要向量元素类型和运算符右侧参数键入相同的类型。
如果你允许右边的参数类型不同,那么它就可以工作,例如:
template<typename T, typename U>
std::vector<T>& operator<<(std::vector<T>& v, U&& element) {
v.emplace_back(std::forward<U>(element));
return v;
}
请注意,我将参数移动到向量中以避免不必要的深层复制,例如按值传入 std::string
。
编辑: 更改为使用 emplace_back
,如评论中所述
如果向量元素的类型和运算符的参数匹配,则以下内容将编译:
std::vector<const char*> v1;
v1 << "Atlanta" << "Dallas" << "Chicago" << "Boston" << "Denver";
同样使用 std::string
文字也适用于 std::string
s 的向量:
using namespace std::string_literals;
std::vector<std::string> v1;
v1 << "Atlanta"s << "Dallas"s << "Chicago"s << "Boston"s << "Denver"s;
可以通过添加另一个模板将 char
数组直接放入 std::string
元素中:
//this template will accept the const char array and construct a string
template<class T, class S, size_t N>
std::vector<S>& operator<<(std::vector<S>& v, const T(& arr)[N])
{
v.push_back({std::begin(arr), std::end(arr)});
//v.push_back(arr); // would also work for char
return v;
}
当你使用
v1 << "Atlanta" << "Dallas" << "Chicago" << "Boston" << "Denver";
参数 T
未推导为 std::string
。对于"Atlanta"
,推导为‘const char [8]
。其他参数的类型将以类似方式推导。
更改函数,以便从 std::vector
.
template<typename Vector>
Vector& operator<<(Vector& v, typename Vector::value_type const& element) {
v.push_back(element);
return v;
}
添加到
template<typename T, typename U>
std::vector<T>& operator<<(std::vector<T>& v, U&& element) {
v.emplace_back(std::forward<U>(element));
return v;
}
与@emlai 使用 std::move
的解决方案相比,这个解决方案使用完美的参数转发,它可以直接将对象移动到向量中,而不是按值传递它。
编辑: 更改为使用 emplace_back,如评论中所述