此代码中发生了什么?太令人困惑了。
#include <utility>
struct check
{
template <typename T>
auto foo() -> decltype(std::declval<T>().value, void())
{
static_assert(T{}.value == 10, "Incorrect value");
}
} var;
int main()
{
struct apple
{
int value{10};
};
var.foo<apple>();
}
特别是它有->
的部分以及之后的所有部分。
答案 0 :(得分:10)
让我们一点一点地经历。
auto foo() -> decltype(std::declval<T>().value, void())
这是一种尾随返回类型。允许使用参数,但这不是必需的。我猜它写得更清楚。 decltype
找到内部表达式的类型,但实际上并未对该表达式求值。 std::declval
用于创建传递给它的类型的实例。这里使用逗号运算符来生成整体返回类型void
,因为逗号运算符计算左侧,抛出它,评估右侧,然后返回。
第一部分创造了一种SFINAE(虽然我从来没有见过像这样使用过)。例如,如果您的foo
重载与value2
而不是value
相同,则不会产生歧义。请参阅here了解我的意思。将其与this one进行比较,{{3}}的返回类型为void
并导致错误。
static_assert(T{}.value == 10, "Incorrect value");
此行确保T
的值初始化实例的value
成员的值为10.如果不是,则生成带有该文本的编译器错误。
} var;
这只是该类使用的全局对象。
struct apple
{
int value{10};
};
这是一个用它来测试它的示例类。它有一个value
成员,该成员在一个值初始化的实例中是10(默认初始化)。
var.foo<apple>();
这只是调用函数。