代码可以简化为
the following
#include <type_traits>
struct some_type {};
struct probe {
template<typename T, std::enable_if_t<!std::is_const<T>::value, int> = 0>
operator T& () const;
};
auto test_call(some_type const&) -> std::false_type;
auto test_call(some_type&) -> std::true_type;
int main() {
static_assert(decltype(test_call(probe{}))::value, "");
}
5
6
一般来说,推导过程试图找到模板参数值,使推导出的值与a相同。但是,有四种情况允许差异:
T
some_type
对于两个函数调用。然后根据[超过.ics.等级]。/
3.3
probe -> some_type& -> some_type&
probe -> some_type& -> const some_type&
所以没有歧义,GCC和Clang是对的。
顺便说一句,如果我们移除
std::enable_if_t<...>
test_all
#include <type_traits>
struct some_type {};
struct probe {
template<typename T>
operator T& () const
{
static_assert(std::is_const_v<T>);
static T t;
return t;
}
};
auto test_call(some_type const&) -> std::false_type;
int main() {
test_call(probe{});
}
static_assert
only under Clang
.也就是说,Clang推断
一些类型
const some_type