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)