当前位置: 首页 > 知识库问答 >
问题:

为什么decltype(declval().func())在decltype(&t::func)不起作用的地方起作用?

弓华茂
2023-03-14
template<typename T, typename = void>
struct ImplementsBaz : public std::false_type { };

template<typename T>
struct ImplementsBaz<T, decltype(&T::baz)> : public std::true_type { };
struct Foo {};
struct Bar { void baz() {} };

std::cout << ImplementsBaz<Foo>::value << std::endl;  // 0
std::cout << ImplementsBaz<Bar>::value << std::endl;  // also 0
template<typename T>
struct ImplementsBaz<T, decltype(std::declval<T>().baz())> : public std::true_type { };

当然,现在只能检测带有0个参数的baz函数。为什么在使用declval ().baz() 时正确选择了专门化,而不是decltype(&t::baz)

共有1个答案

贺景胜
2023-03-14

如果您使用void_t“检测习惯用法”,那么它确实如预期的那样工作:

template <typename...> using void_t = void;

template <typename T>
struct ImplementsBaz<T, void_t<decltype(&T::baz)>> : std::true_type {};


struct Bar { void baz() {} };

static_assert(ImplementsBaz<Bar>::value); // passes

戈德博尔特连杆

至于为什么,这个问题详细解释了“void_t技巧”是如何工作的。引用公认的答案:

 类似资料:
  • 问题内容: 我有以下定义: 我尝试按如下方式调用它,但收到错误消息: 这符合: 问题答案: 该相关转到FAQ中指出,和«别在内存相同的表示»。 要了解原因,让我们剖析两件事: 切片是一个后备存储阵列,外加几个包含切片大小和容量的整数。 在Go中,数组并不是某种意义上的“高级”。相反,它们包含的元素的布局是严格定义的:它们全部包含在内存的相邻区域中,彼此相邻。 这意味着,在切片的支持数组中,元素是类

  • 问题内容: 您可以运行此命令并告诉我为什么结果集只有两行吗?它应该有三个,看起来像这样… 这是sql,因此您可以将其粘贴到查询工具中 我无法弄清楚为什么#appSteps中的所有3个非空行都没有返回 问题答案: 原因是因为您在子句中包含了右侧表。您应该将其移至以下条件: 这样做的原因是,该子句是 在后面 进行评估的,然后从中过滤出您的结果。 在子句中包含的右手表(或的左手表)可将转换为。

  • 问题内容: 我正在尝试从JSON网址获取集合。骨干网确实发送了请求并得到了响应,但是在它之后的集合中没有: 这是我的JavaScript: 响应中的JSON 响应中的Content-Type HTTP标头为。 为什么不将其加载到集合中?JSON是否正确? 一些更多的代码: 问题答案: 是异步的。尝试 要么 要么

  • 问题内容: 我有三部分字符串,每个部分用 符号分隔 。例如, 现在,当我使用这样的方法拆分它时: 它包含整个字符串作为单个元素的数组。 但是当我使用这个: 它完美的作品是什么,我想这意味着 现在的数组包含,并分别对指数0,1和2。 我想知道为什么第一次使用时不起作用,因为我在使用 问题答案: 因为字符是在正则表达式中用来标记行尾的保留令牌。因此,您必须使用进行 转义。

  • 问题内容: 我现在有点困惑。我尝试过: 并得到: 但是,我想要: 我的代码有什么问题? 问题答案: 您没有将其分配给。字符串是 不可变的 。 您需要将其分配回。

  • 问题内容: 我正在尝试这样做: 第一行有效: 但是接下来的两个: 和 只是输出 为什么? 问题答案: 因为你需要加入同,只是列出了内容直接,内容不具有完整路径。 范例- 如果未提供完整路径,则在当前目录中搜索,因此当您给出时,将获得正确的列表。 范例- 假设某个文件夹-具有文件-并在其中。 当您执行-时,返回的列表类似于- 即使您在其中提供绝对路径,列表中返回的文件也将具有指向目录的相对路径。您将