2016-12-01 64 views
2
#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爲什麼在這個例子中SFINAE不能按預期工作?

我的代碼有什麼問題?

+1

應該是'typename iterator_traits :: iterator_category'。否則,這個C++ 14版的http://coliru.stacked-crooked.com/a/461c077a5cb8fcbc對我來說效果很好:輸出'true'。 – AnT

+2

另外,兩次重複的true_type似乎是一個錯字。 – Eugene

+1

爲什麼不使用這個簡單的代碼'std :: is_convertible :: iterator_category,std :: input_iterator_tag>'。它會在您忘記輸入名稱時發出警告 – Danh

回答

1

您錯過了typename

缺乏一個typename使得當替補T

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 
>; 

失敗。默認情況下,iterator_traits<T>::iterator_category被假定爲一個值。對於您的特定T,這是一種類型(所有T都是如此)。這似乎被您的編譯器視爲替換錯誤(我不確定您的編譯器是否正確)。

一旦is_pure_input_iterator被替換失敗排除,則選擇其他超載,即false_type

iterator_traits<T>::iterator_category之前添加typename解決了您的問題,因爲@ AnT2注意到here


作爲is_convertible_v需要一個類型作爲其第一個參數,無論Titerator_traits<T>::iterator_category只能是一個值,你可以is_pure_input_iterator可證明有沒有T,使得它沒有此故障。要麼有一個規則來檢測這個,並生成一個診斷(你的編譯器不會發出),你的程序是不合格的,因爲它沒有診斷要求。

相關問題