我有一个模板化函数需要指针。声明一个模板参数是一个迭代器/指针
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