我正在尝试编写一个泛型函数,它将返回任何容器的大小,该函数具有size()
方法和size_type
定义。到目前为止,我尝试了两种方法,但都没有编译:
1
template <typename Cont>
auto len(Cont const& cont) -> decltype(std::declval<Cont&>().size(), Cont::size_type)
{
return cont.size();
}
2
template <typename T, template <typename U, typename = std::allocator<U>> typename Cont>
auto len(Cont<T> const& cont) -> decltype(std::declval<Cont<T>&>().size(), Cont<T>::size_type)
{
return cont.size();
}
尝试测试它:
std::vector<int> vec;
auto sz = len(vec);
显然,当我删除尾随decltype()
时,所有内容都会按预期进行。我知道,这也可以通过std::enable_if
来实现,但是出于教育的考虑,我必须想到这一点。请解释我缺少的东西
P.S。对于那些将问题标记为重复的人,我不是在问“我在哪里以及为什么要把”模板“和”typename“关键字放进去?”,因为当我写这个问题时,我尚未弄明白,这就是我所缺少的
答案 0 :(得分:2)
您必须添加typename
和几个括号
decltype(std::declval<Cont&>().size(), typename Cont::size_type{} )
// ....................................^^^^^^^^................^^
typename
需要说size_type
是Cont
内的类型。
关于括号...记入decltype()
返回对象类型的计数。如果你只是写
decltype( typename Cont::size_type )
您要求检测类型中的类型,decltype()
不能以这种方式工作;你必须构造一个Cont::size_type
类型的对象(所以括号),以便decltype()
可以检测到类型。