【C++ troubleshooting】A case about decltype
template <typename iter_t>
bool next_permutation(iter_t beg, iter_t end) {
//
if (beg == end || beg + 1 == end) {
return false;
}
//在白板上写代码别忘了加 }
for (int *i = end - 2; i >= beg; --i) {
auto iter = std::lower_bound(i + 1, end, *i, std::greater<decltype(*beg)>{});
if (iter != i + 1) {
std::swap(*(iter - 1), *i);
std::reverse(i + 1, end);
return true;
}
}
return false;
}
ptr_t ptr;
*ptr;
As we know, in C++, for a variable ptr
of a pointer (or iterator) type, the expression *ptr
returns a reference to the object that ptr
points to.
Suppose the object that ptr
points to is of type T
, then decltype(*ptr)
will yield the type T&
.
So, in the above code, the line
auto iter = std::lower_bound(i + 1, end, *i, std::greater<decltype(*beg)>{});
becomes
auto iter = std::lower_bound(i + 1, end, *i, std::greater<int&>{});
when the function template next_permutation
is instantiated.
However, such an instantiation of std::lower_bound
will not compile.
Let's see the compile error:
In file .../include/c++/8.3.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_comp_val<_Compare>::operator()(_Iterator, _Value&) [with _Iterator = int*; _Value = const int; _Compare = std::greater<int&>]': .../include/c++/8.3.0/bits/predefined_ops.h:177:11: error: no match for call to '(std::greater<int&>) (int&, const int&)' { return bool(_M_comp(*__it, __val)); } ^~~~~~~~~~~~~~~~~~~~~~~~~~~ In file .../include/c++/8.3.0/bits/predefined_ops.h:177:11:error: binding reference of type 'int&' to 'const int' discards qualifiers { return bool(_M_comp(*__it, __val)); } ^~~~~~~~~~~~~~~~~~~~~~~~~~~
将其中提到的函数片段,还原如下
template<typename _Compare>
struct _Iter_comp_val
{
_Compare _M_comp;
// constructors
template<typename _Iterator, typename _Value>
bool
operator()(_Iterator __it, _Value& __val)
{ return bool(_M_comp(*__it, __val)); }
};
这个问题我还没搞懂。