c++ - 错误:使用通用引用的声明冲突
问题描述
我想从文章中实现通用反向功能,它适用于右值。但没有左值。
#include <iostream>
#include <vector>
#include <functional>
template <typename T>
class Reverse
{
T iterable_;
public:
explicit Reverse(T&& iterable) : iterable_(std::forward<T>(iterable)){}
auto begin() { return std::rbegin(iterable_); }
auto end() { return std::rend(iterable_); }
};
std::vector<int> CreateVector()
{
return {0,1,2,3,4,5,6,7,8,9};
}
int main()
{
std::vector<int> v{1,2,3,4,5,6,7}; // line 23
for(const auto& i : Reverse(CreateVector()))
std::cout << i << " ";
std::cout << std::endl;
Reverse(v); // line 29
// for(const auto& i : Reverse(v))
// std::cout << i << " ";
return 0;
}
我收到左值错误:
main.cpp: In function 'int main()':
main.cpp:29:13: error: conflicting declaration 'Reverse<...auto...> v'
29 | Reverse(v);
| ^
main.cpp:23:22: note: previous declaration as 'std::vector<int> v'
23 | std::vector<int> v{1,2,3,4,5,6,7};
|
你能告诉我正确解决方案的方向吗?
解决方案
首先,您不使用通用/转发参考,您只需使用普通的 R 值参考。
你想要语法template<class T> F(T&&)
(构造函数必须是模板函数):
template<class F>
explicit Reverse(F&& iterable) : iterable_(std::forward<T>(iterable)){}
如果你使用 C++17 或更高版本,可以添加推导指南:
template<class T>
Reverse(T&&) -> Reverse<T>;
通过在上面添加,您不必在实例化Reverse
其对象时显式指定类的模板参数。如果没有 CTAD,您需要编写:Reverse<decltype(v)>(..)
处理 R 值或Reverse<decltype((v))>
L 值(需要大多数内括号来获取容器的 L 值引用)。
如果你想创建临时Reverse
作为v
参数,只需写:
Reverse{v};
(现在为Reverse(v)
您重新声明v
变量)或命名实例:
Reverse withLvalue(v);
推荐阅读
- migradoc - 检查一行的 MigraDoc 字体是否为粗体
- java - JAVAFX 应用程序 UI 变得无响应
- python - zip 文件的 Python S3 上传给出 AttributeError: 'ZipFile' object has no attribute 'tell' 错误
- java - 为什么 flatMap 后采集会改变 Stream 处理顺序?
- silverstripe - SilverStripe Ajax 和页面控制器
- ruby-on-rails - 如何在不更改这些页面上的任何内容的情况下将模板化网页包含到 ruby on rails 应用程序中
- java - 有以下三种方法
- javascript - How to get(extract) Quill editor icon in .jpg/.png format? (they only have SVG format)
- spring - Spring 3 与 spring-data-jpa
- c# - 通过 C# 获取 Json 列差异