【发布时间】:2021-09-27 17:22:57
【问题描述】:
C++ 模板 - 完整指南第 2 版在第 435 页提供了以下代码
#include <string>
#include <type_traits>
template<typename T, typename = void>
struct HasBeginT : std::false_type {};
template<typename T>
struct HasBeginT<T, std::void_t<decltype(std::declval<T>().begin())>>
: std::true_type {};
并且 cmets 使用 decltype(std::declval<T>().begin()) 来测试在 T 上调用 .begin() 是否有效。
我认为这一切都说得通……
让我吃惊的是脚注中的评论:
除了
decltype(<i>call-expression</i>)不需要非引用,非void返回类型是完整的,这与其他上下文中的调用表达式不同。改用decltype(std::declval<T>().begin(), 0)确实增加了调用的返回类型是完整的要求,因为返回的值不再是decltype操作数的结果。
我真的不明白。
为了尝试使用它,我尝试使用以下代码查看void 成员begin 的行为
struct A {
void begin() const;
};
struct B {
};
static_assert(HasBeginT<A>::value, "");
static_assert(!HasBeginT<B>::value, "");
但是无论有没有, 0,这两个断言都会通过。
【问题讨论】:
标签: c++ templates c++17 decltype void-t