Skip to content

Commit ff4a4ff

Browse files
committed
Workaround for compilation failure on MSVC
This commit depends on #27. There is implementation divergence as to whether the following code is accepted: template <typename T> struct foo { static constexpr auto baz() { return 0; } using quux = decltype(baz); }; It is accepted by GCC and Clang, and rejected by MSVC and sometimes by EDG: https://godbolt.org/z/dW964rqec Because the calculation of the iterator_category depended on code of this form, previously, MSVC would fail to compile iterator_interface with this error: error C3539: a template-argument cannot be a type that contains 'auto' In order to work around this issue, the static member function-based metaprogramming has been replaced with the use of std::conditional_t. After this change, MSVC successfully compiles and runs all the tests.
1 parent 47c8faa commit ff4a4ff

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

include/beman/iterator_interface/iterator_interface.hpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,17 @@ struct iter_cat<IteratorConcept, ReferenceType, false> {};
142142

143143
template <typename IteratorConcept, typename ReferenceType>
144144
struct iter_cat<IteratorConcept, ReferenceType, true> {
145-
private:
146-
static constexpr auto compute_category_tag() {
147-
if constexpr (!std::is_reference_v<ReferenceType>) {
148-
return std::input_iterator_tag{};
149-
} else if constexpr (std::is_base_of_v<std::random_access_iterator_tag, IteratorConcept>) {
150-
return std::random_access_iterator_tag{};
151-
} else if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, IteratorConcept>) {
152-
return std::bidirectional_iterator_tag{};
153-
} else {
154-
return std::forward_iterator_tag{};
155-
}
156-
}
157-
158-
public:
159-
using iterator_category = std::invoke_result_t<decltype(compute_category_tag)>;
145+
using iterator_category =
146+
std::conditional_t<
147+
!std::is_reference_v<ReferenceType>,
148+
std::input_iterator_tag,
149+
std::conditional_t<
150+
std::is_base_of_v<std::random_access_iterator_tag, IteratorConcept>,
151+
std::random_access_iterator_tag,
152+
std::conditional_t<
153+
std::is_base_of_v<std::bidirectional_iterator_tag, IteratorConcept>,
154+
std::bidirectional_iterator_tag,
155+
std::forward_iterator_tag>>>;
160156
};
161157

162158
} // namespace detail

0 commit comments

Comments
 (0)