【问题标题】:For what T does `std::declval<T>()` not have a matching function?`std::declval<T>()` 没有匹配函数的原因是什么?
【发布时间】:2019-10-06 20:04:21
【问题描述】:

我惊讶地发现对于某些Tdecltype(std::declval&lt;T&gt;()) 是不合法的:

#include <utility>

template<typename T>
using Alias = decltype(std::declval<T>());

// as expected
using A1 = Alias<int>;
using A2 = Alias<int(int)>;

// error: no matching function for call to 'declval<...>()'
using A3 = Alias<int(int) const>;
using A4 = Alias<int(int) volatile>;
using A5 = Alias<int(int) &>;
using A6 = Alias<int(int) &&>;
// and all combinations of the above

cppreference 似乎并不表示预期会出现此错误。

还有其他不能使用declval&lt;T&gt; 的类型吗?规范在哪里定义这些?

【问题讨论】:

  • 在函数原型类型之后放置属性似乎会引发错误。您可能必须在以下类型上使用 std::functionAlias&lt;std::function&lt;int(int)&gt; const&gt;
  • @D.Nathanael 这会改变语义。 std::function 是关于类型擦除的。
  • std::function&lt;int(int)&gt; const 类似于 int(const*)(int),而不是 int(*)(int) const

标签: c++ language-lawyer declval


【解决方案1】:

根据[declval]declval 的签名是:

template <class T>
add_rvalue_reference_t<T> declval() noexcept;

因此,如果 add_rvalue_reference_t&lt;T&gt; 不能作为返回类型说明符出现,则该调用是不正确的。

合格的函数类型有一个特殊的规则:

具有 cv-qualifier-seqref-qualifier 的函数类型 (包括由 typedef-name ([dcl.typedef], [temp.param])) 应仅显示为:

  • (6.1) 非静态成员函数的函数类型,

  • (6.2) 成员指针所指的函数类型,

  • (6.3) 函数 typedef 声明或 alias-declaration 的顶级函数类型,

  • (6.4) type-parameter 的默认参数中的 type-id,或

  • (6.5) type-parameter ([temp.arg.type]) 的模板参数的 type-id

它们不能是返回类型说明符。

查看Types,我很确定合格的函数类型是唯一的情况。

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多