【问题标题】:decltype filtering for container as template parameter [duplicate]容器的decltype过滤作为模板参数[重复]
【发布时间】:2017-10-03 11:46:29
【问题描述】:

我正在尝试编写一个通用函数,它将返回具有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 实现,但为了教育起见,我必须弄清楚这一点。请解释我缺少什么

附:对于要将问题标记为重复的任何人,我不是在问“我必须在哪里以及为什么要放置“模板”和“类型名称”关键字?”,因为当我写这个问题时,我还没弄清楚,这就是我所缺少的

【问题讨论】:

  • 顺便说一句,有std::size()...
  • 是的,我知道。关键是,这不是我要实现的唯一功能,所以我必须正确获取模式。
  • std::declval有点多余,因为你可以访问cont,你可以写decltype(cont.size(), typename Cont::size_type)
  • @Holt 你说得对,我后来也注意到了这一点

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


【解决方案1】:

你必须添加一个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() 可以检测到类型。

【讨论】:

  • 天哪,这是一个愚蠢的陷阱,类型为 typename :)。非常感谢!这只是我第一次发现可以以这种方式使用 decltype。
猜你喜欢
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
相关资源
最近更新 更多