【发布时间】:2018-06-11 02:38:43
【问题描述】:
假设我想编写一个通用函数,从集合中打印出标准输出范围。既然它应该是通用的,我假设......
std::vector<std::string> names = { "John", "Henry", "Mark" };
还有:
std::vector<int> years = { 100, 200, 400 };
..将可以打印出来。
由于集合的类型可能不同,并且 STL 集合没有基类让我有机会传递基类迭代器,所以我使用模板函数:
template<typename TIterator>
void PrintRange( TIterator beginIter,TIterator endIter )
{
for( auto it = beginIter; it != endIter; ++it )
{
std::cout << *it << std::endl;
}
}
现在一切正常,现在我可以写了:
PrintRange( names.begin(), names.end() );
和:
PrintRange( years.begin(), years.end() );
但是现在我想帮助我的功能的客户更快地理解为什么在他使用它时会出现错误。现在当我打电话时:
PrintRange( 100, 400 );
有错误:
main.cpp:23:34: 错误:一元‘*’的无效类型参数(有‘int’)
我想打印如下内容:
其中一个参数与预期的参数类型不对应 '迭代器'
那么解决这个问题的最佳方法是:
注意错误消息是否不正确并不重要 和我预期的一样有意义。用户应分析模板类代码以 找出他错误的原因。
使用 static_assert 断言所有已知的可能性.. 但是由于没有基类,如何断言函数的参数是 ANY 迭代器?
static_assert(std::is_base_of::iterator >::value);
这只会断言字符串迭代器的向量...
【问题讨论】:
-
为什么开始和结束迭代器的类型不同?他们应该是同一个
-
如果您在函数中添加了良好的文档,那么用户无需检查您的任何模板代码,您也无需投入任何额外的精力来验证输入。让编译器验证!