2015-07-28 43 views
0

我有一個模板化函數需要指針。聲明一個模板參數是一個迭代器/指針

template <typename T> 
void foo(const T* bar){} 

如何更改foo以確保我正在傳遞迭代器/指針?我假設有一個static_assertenable_if這樣做的方式,但我似乎無法找到它。

+0

爲什麼不簡單使用由模板機制提供的隱式接口?只要做好你的函數體就好像你傳遞了一個迭代器/指針一樣,它將適用於所有「看起來像」的東西。 – Telokis

+0

@Ninetainedo如果我打算在我的界面中公開這個函數,我需要做一些防禦性編程。理想地提供使用'foo'實現不正確的接口信息。 –

+0

如果你真的想這樣做,我知道有一個'std :: is_pointer' type_trait,但我不知道迭代器。 – Telokis

回答

1

您可以使用std::iterator_traits檢查它是否是一個迭代器(或指針)

template <typename IT> 
decltype(std::iterator_traits<IT>::iterator_category{}, void()) 
foo(IT bar); 
+0

這似乎是正確的解決方案:「如果迭代器不具有五種成員類型difference_type,value_type,pointer,reference和iterator_category,那麼這個模板沒有成員類型(std :: iterator_traits對SFINAE友好)」[[源代碼](http://en.cppreference.com/w/cpp/iterator/iterator_traits)] –

0

要檢查指針,你可以使用std::is_pointer。要檢查迭代器,可以按照this answer中的描述來定義自己的is_iterator特徵。如果將這兩者結合起來,您會得到:

#include <type_traits> 
#include <iterator> 

template<typename T, typename = void> 
struct is_iterator 
{ 
    static constexpr bool value = false; 
}; 

template<typename T> 
struct is_iterator<T, typename std::enable_if< 
    !std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type> 
{ 
    static constexpr bool value = true; 
}; 

template<class T> 
void test(T t) { 
    static_assert(std::is_pointer<T>::value || is_iterator<T>::value, 
       "T must be pointer or iterator"); 
} 
+0

指針**是**迭代器。 – Jarod42

相關問題