std :: reference_wrapper问题

Lin*_*gxi 17 c++ language-lawyer implicit-conversion c++11 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;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用注释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本身.有人可以向我解释一下吗?

Bar*_*rry 20

问题是非成员operator<for std::vector是一个功能模板:

template< class T, class Alloc >
bool operator<( const vector<T,Alloc>& lhs,
                const vector<T,Alloc>& rhs );
Run Code Online (Sandbox Code Playgroud)

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

如果参数类型不包含参与模板参数推导的模板参数,则将对函数参数执行隐式转换(第4节)以将其转换为相应函数参数的类型.

但在这种情况下,参数类型确实参与演绎.这就是为什么它找不到的原因.如果我们写了自己的模板operator<:

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

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

std::cout << (refa.get() < refb.get()) << '\n';
Run Code Online (Sandbox Code Playgroud)