c++ - std::reference_wrapper 的问题

标签 c++ c++11 language-lawyer implicit-conversion reference-wrapper

使用以下代码可以明确问题:

#include <functional>
#include <iostream>
#include <vector>

int main() {
  //std::vector<int> a, b;
  int a = 0, b = 0;
  auto refa = std::ref(a);
  auto refb = std::ref(b);
  std::cout << (refa < refb) << '\n';
  return 0;
}

如果我使用注释 std::vector<int> a, b;而不是 int a = 0, b = 0; ,则代码无法在 GCC 5.1、clang 3.6 或 MSVC'13 中的任何一个上编译。在我看来,std::reference_wrapper<std::vector<int>>可隐式转换为 std::vector<int>&这是 LessThanComparable,因此它本身应该是 LessThanComparable。有人可以向我解释一下吗?

最佳答案

问题在于非成员(member) operator< 对于 std::vector是一个函数模板:

template< class T, class Alloc >
bool operator<( const vector<T,Alloc>& lhs,
                const vector<T,Alloc>& rhs );

这里做模板类型推导时考虑隐式转换,[temp.arg.explicit]强调if:

Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.

但是在这种情况下,参数类型确实参与了推导。这就是它找不到的原因。如果我们编写自己的-模板operator< :

bool operator<(const std::vector<int>& lhs, const std::vector<int>& rhs)
{
    return true;
}

您的代码将按预期工作。但是,要使用通用的,您必须明确地提取引用:

std::cout << (refa.get() < refb.get()) << '\n';

关于c++ - std::reference_wrapper 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30263007/

相关文章:

C++ 从其线程函数中引用一个 boost::thread

c++ - 确定范围内的元素放置在连续内存中

c++ - 内联模板特化

c++ - 如何在 C++ 模板中使用类作为参数

c++ - 为什么编译器不为 size_t 的负值生成警告?

c++ - 通过 reinterpret_cast 的非对齐访问

c++ - 获取 Hugepagesize 的 Linux API

C++11 在 Lambda 中捕获成员变量

c++ - 恢复生命周期已经结束的对象的成员函数协程是UB吗?

c++ - 符合标准的 C++ 实现如何表明它不知道当前日期和时间?