@@ -1966,27 +1966,29 @@ struct iterator_state {
1966
1966
};
1967
1967
1968
1968
// Note: these helpers take the iterator by non-const reference because some
1969
- // iterators in the wild can't be dereferenced when const.
1970
- template <typename Iterator>
1969
+ // iterators in the wild can't be dereferenced when const. C++ needs the extra parens in decltype
1970
+ // to enforce an lvalue. The & after Iterator is required for MSVC < 16.9. ResultType cannot be
1971
+ // reused for result_type due to bugs in ICC, NVCC, and PGI. See #3293.
1972
+ template <typename Iterator, typename ResultType = decltype ((*std::declval<Iterator &>()))>
1971
1973
struct iterator_access {
1972
- using result_type = decltype((*std::declval<Iterator>()));
1973
- // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1974
+ using result_type = decltype((*std::declval<Iterator & >()));
1975
+ // NOLINTNEXTLINE(readability-const-return-type)
1974
1976
result_type operator ()(Iterator &it) const {
1975
1977
return *it;
1976
1978
}
1977
1979
};
1978
1980
1979
- template <typename Iterator>
1981
+ template <typename Iterator, typename ResultType = decltype (((*std::declval<Iterator &>()). first )) >
1980
1982
struct iterator_key_access {
1981
- using result_type = decltype(((*std::declval<Iterator>()).first));
1983
+ using result_type = decltype(((*std::declval<Iterator & >()).first));
1982
1984
result_type operator ()(Iterator &it) const {
1983
1985
return (*it).first ;
1984
1986
}
1985
1987
};
1986
1988
1987
- template <typename Iterator>
1989
+ template <typename Iterator, typename ResultType = decltype (((*std::declval<Iterator &>()). second )) >
1988
1990
struct iterator_value_access {
1989
- using result_type = decltype(((*std::declval<Iterator>()).second));
1991
+ using result_type = decltype(((*std::declval<Iterator & >()).second));
1990
1992
result_type operator ()(Iterator &it) const {
1991
1993
return (*it).second ;
1992
1994
}
0 commit comments