2015-07-28 82 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