cpp sfinae

cpp 模板SFINAE(“Substitution Failure Is Not An Error”)

下面是一段引文,来自网站 https://en.cppreference.com/w/

1
2
3
This rule applies during overload resolution of function templates: When substituting the explicitly specified or deduced type for the template parameter fails, the specialization is discarded from the overload set instead of causing a compile error.

This feature is used in template metaprogramming.

推断辅助函数:decay_t / decltype

涉及:函数重载(overload) / 参数计算后进栈

一般特化的时候,其特化参数小于等于模板参数,这是因为特化参数对应模板参数进行 ”赋值“行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



// ellipsis parameter has the lowest ranking for overload resolution
void (...)
{
std::cout << "Catch-all overload calledn";
}

// this overload is added to the set of overloads if
// C is a reference-to-class type and F is a pointer to member function of C
// (void)(c.*f)(), void()
// the return type is void()
// but (void)(c.*f)(), void() execute comma
template <class C, class F>
auto (C c, F f) -> decltype((void)(c.*f)(), void())
{
std::cout << "Reference overload calledn";
}

// this overload is added to the set of overloads if
// C is a pointer-to-class type and F is a pointer to member function of C
template <class C, class F>
auto (C c, F f) -> decltype((void)((c->*f)()), void())
{
std::cout << "Pointer overload calledn";
}

struct X { void f() {} };

int main(){
X x;
test( x, &X::f);
test(&x, &X::f);
test(42, 1337);
}
//output
// Reference overload called
// Pointer overload called
// Catch-all overload called