Date: Thu, 14 Jan 2021 15:18:33 -0500
Inspired by the combination of the recent thread on static_assert in
constexpr and a problem I ran into with real code... Consider the following:
template <typename T>
void foo(volatile std::atomic<T>*,
typename std::atomic<T>::value_type)
{}
template <typename T>
void foo(std::shared_ptr<T>*, std::shared_ptr<T>)
{}
std::shared_ptr<std::vector<int>> a;
foo<std::vector<int>>(&a, a);
(Live demo: https://godbolt.org/z/r6GMhY)
It *looks* like this code ought to compile... and indeed, it compiles
*if* the template parameter is removed from the invocation of `foo`.
Without it, however, the static_assert that is tripped trying to
evaluate std::atomic<T>::value_type for the first overload halts
compilation, even though the first overload isn't viable *anyway*.
This... seems undesirable, and contrary to SFINAE. Is this intended?
(See also https://stackoverflow.com/questions/65722107. I didn't check
MSVC, but this happens with both GCC and Clang.)
constexpr and a problem I ran into with real code... Consider the following:
template <typename T>
void foo(volatile std::atomic<T>*,
typename std::atomic<T>::value_type)
{}
template <typename T>
void foo(std::shared_ptr<T>*, std::shared_ptr<T>)
{}
std::shared_ptr<std::vector<int>> a;
foo<std::vector<int>>(&a, a);
(Live demo: https://godbolt.org/z/r6GMhY)
It *looks* like this code ought to compile... and indeed, it compiles
*if* the template parameter is removed from the invocation of `foo`.
Without it, however, the static_assert that is tripped trying to
evaluate std::atomic<T>::value_type for the first overload halts
compilation, even though the first overload isn't viable *anyway*.
This... seems undesirable, and contrary to SFINAE. Is this intended?
(See also https://stackoverflow.com/questions/65722107. I didn't check
MSVC, but this happens with both GCC and Clang.)
-- Matthew
Received on 2021-01-14 14:18:37