我有一個模板化函數需要指針。聲明一個模板參數是一個迭代器/指針
template <typename T>
void foo(const T* bar){}
如何更改foo
以確保我正在傳遞迭代器/指針?我假設有一個static_assert
或enable_if
這樣做的方式,但我似乎無法找到它。
我有一個模板化函數需要指針。聲明一個模板參數是一個迭代器/指針
template <typename T>
void foo(const T* bar){}
如何更改foo
以確保我正在傳遞迭代器/指針?我假設有一個static_assert
或enable_if
這樣做的方式,但我似乎無法找到它。
您可以使用std::iterator_traits
檢查它是否是一個迭代器(或指針)
template <typename IT>
decltype(std::iterator_traits<IT>::iterator_category{}, void())
foo(IT bar);
這似乎是正確的解決方案:「如果迭代器不具有五種成員類型difference_type,value_type,pointer,reference和iterator_category,那麼這個模板沒有成員類型(std :: iterator_traits對SFINAE友好)」[[源代碼](http://en.cppreference.com/w/cpp/iterator/iterator_traits)] –
要檢查指針,你可以使用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");
}
指針**是**迭代器。 – Jarod42
爲什麼不簡單使用由模板機制提供的隱式接口?只要做好你的函數體就好像你傳遞了一個迭代器/指針一樣,它將適用於所有「看起來像」的東西。 – Telokis
@Ninetainedo如果我打算在我的界面中公開這個函數,我需要做一些防禦性編程。理想地提供使用'foo'實現不正確的接口信息。 –
如果你真的想這樣做,我知道有一個'std :: is_pointer' type_trait,但我不知道迭代器。 – Telokis