我如何定义一个函数,它将迭代器作为输入作为任何类型的STL容器,但仅限于特定模板类型的那些.例如:
任何形式的迭代器std::list<Unit*>::iterator 或 std::vector<Unit*>::iterator
我只想定义要采用的函数std::list<Unit*>::iterator,但是如果我们切换到不同的STL容器,我不想更改我的代码.
有没有办法用模板或其他方式做到这一点?
ice*_*ime 15
您可以使用SFINAE构造,例如boost :: enable_if,它验证嵌套的typedef iterator::value_type是否确实是合适的类型.
template<class T, class Iterator>
typename boost::enable_if<boost::is_same<typename Iterator::value_type, T> >::type
f(Iterator i)
{
/* ... */
}
int main()
{
std::list<int> l;
std::vector<int> v;
f<int>(l.begin()); // OK
f<int>(v.begin()); // OK
std::vector<float> v2;
f<int>(v2.begin()); /* Illegal */
}
Run Code Online (Sandbox Code Playgroud)
这就是我所理解的"一个函数,它将迭代器作为任何类型的STL容器的输入,但仅限于特定模板类型的那些",但我的解释可能是错误的.
jal*_*alf 14
除了依赖于SFINAE的现有答案之外,更简单的近似是简单地定义函数以将任意模板类型作为迭代器:
template <typename Iter>
void function(Iter first, Iter last){
Unit* val = *first;
}
Run Code Online (Sandbox Code Playgroud)
这有一些缺点.与SFINAE解决方案(例如boost::enable_if)不同,这并不能完全满足您的要求.只要类型的对象Iter可以被解除引用而产生可转换为Unit*的值,这就编译,这不是完全相同的事情.您无法保证它Iter是完全符合STL的迭代器(它可能只是另一种定义的类型operator*),或者它的值类型是Unit*精确的.
另一方面,它更简单.
你只想迭代容器my_special_type?在这种情况下:
template <bool, typename T>
struct enable_if;
template <typename T>
struct enable_if<true, T>
{
typedef T type;
};
template <typename T, typename U>
struct is_same
{
enum {value = false};
};
template <typename T>
struct is_same<T, T>
{
enum {value = true};
};
template <typename Iter>
typename enable_if<is_same<typename Iter::value_type, your_special_type>::value,
void>::type
function(Iter begin, Iter end)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
模板的另一种方法是在不满足条件时触发静态断言.
#include <iterator>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
template <class Type, class Iter>
void foo(Iter from, Iter to)
{
BOOST_STATIC_ASSERT((boost::is_same<typename std::iterator_traits<Iter>::value_type, Type>::value));
//...
}
int main()
{
int arr[10];
foo<int>(arr, arr + 10); //OK
foo<double>(arr, arr + 10); //triggers static assertion
}
Run Code Online (Sandbox Code Playgroud)
如果你想取消模板,那么也可以使用类型擦除来编写"any_iterator".例如,像这样:http://stlab.adobe.com/classadobe_1_1any__iterator.html
| 归档时间: |
|
| 查看次数: |
5468 次 |
| 最近记录: |