#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
constexpr auto is_pure_input_iterator(int) ->
conditional_t
<
is_convertible_v
<
iterator_traits<T>::iterator_category,
input_iterator_tag
>,
true_type, false_type
>;
template<typename>
constexpr false_type is_pure_input_iterator(...);
int main()
{
cout << boolalpha
<< decltype(is_pure_input_iterator<istream_iterator<int>>(0))::value
<< endl;
return {};
}
预期输出应为:true
,但实际值为false
。
我的代码有什么问题?
答案 0 :(得分:1)
您错过了typename
。
缺少typename
会使
template<typename T>
constexpr auto is_pure_input_iterator(int) ->
conditional_t
<
is_convertible_v
<
iterator_traits<T>::iterator_category,
input_iterator_tag
>,
true_type, false_type
>;
替换T
时失败。默认情况下,iterator_traits<T>::iterator_category
被假定为值。对于您的特定T
,它是一种类型(对于所有T
都是如此)。这似乎被编译器视为替换错误(我不确定您的编译器是否正确 1 )。
替换失败后排除is_pure_input_iterator
后,会选择另一个重载,即false_type
。
在typename
之前添加iterator_traits<T>::iterator_category
可以解决您的问题,因为@ AnT2注意到here。
1 由于is_convertible_v
需要一个类型作为其第一个参数,并且无论T
iterator_traits<T>::iterator_category
只能是一个值,您的is_pure_input_iterator
可以证明没有T
,因此它没有失败。要么检测到这一点并生成诊断(编译器不会发出),或您的程序格式不正确,因此不需要诊断。