decltype过滤容器作为模板参数

时间:2017-10-03 11:46:30

标签: c++ templates c++14 sfinae decltype

我正在尝试编写一个泛型函数,它将返回任何容器的大小,该函数具有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“关键字放进去?”,因为当我写这个问题时,我尚未弄明白,这就是我所缺少的

1 个答案:

答案 0 :(得分:2)

您必须添加typename和几个括号

decltype(std::declval<Cont&>().size(), typename Cont::size_type{} )
// ....................................^^^^^^^^................^^

typename需要说size_typeCont内的类型。

关于括号...记入decltype()返回对象类型的计数。如果你只是写

decltype( typename Cont::size_type )

您要求检测类型中的类型,decltype()不能以这种方式工作;你必须构造一个Cont::size_type类型的对象(所以括号),以便decltype()可以检测到类型。