c++ - 错误: conflicting declaration using universal references

标签 c++ templates forwarding-reference

我想实现 article 中的通用反向功能它适用于右值。但不适用于左值。

#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);

Demo

关于c++ - 错误: conflicting declaration using universal references,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60168623/

相关文章:

c++ - boost 程序选项对值

c++ - 只用一个头文件开始一个新项目

C++:如何模板化一个集合?

c++ - 转发引用是否仍然是右值引用?

c++ - 为什么在这种情况下转发引用不起作用?

c++ - 用于散列编译时字符串的延迟指针

c++ - Qt:Qt5 Windows 中 BitBlt 的替代品

c++ - 如何使用模板将 QString 转换为类型名?

file - 读取文件作为模板,执行并写回

C++通用引用和LRef参数的类型推导