SFINAE
- Substitution Failure Is Not An Error
- 치환(Substitution) 이 실패하면 에러를 내지 않고 다른 적당한 것을 찾는다
template<typename T>
typename T::type foo(T t) //int::type foo(int t) -> Substitution Failure
{}
void foo(...) {}
int main()
{
foo(3); // foo(...)
}
template<typename T>
void foo(T t)
{
static_assert( is_integral<T>::value, "error" );
}
- 빌드에러 (static_assert) 를 내고 싶은게 아니고 foo(…) 를 호출하게 하고 싶다면?
// 리턴타입에서 Substitution Failure
template<typename T>
typename enable_if<is_integral<T>::value>::type foo(T t)
{
cout << "T" << endl;
}
// 리턴타입이 없는 생성자는?
template<typename T>
void foo(T t,
typename enable_if<is_integral<T>::value>::type* = nullptr)
{
cout << "T" << endl;
}
// template 인자로 빼기
template<typename T,
typename enable_if<is_integral<T>::value>::type* = nullptr>
void foo(T t)
{
cout << "T" << endl;
}
void foo(...)
{
cout << "..." << endl;
}
template<typename T>
typename enable_if<is_pointer<T>::value>::type
print(const T& t)
{
cout << t << " : " << *t << endl;
}
template<typename T>
typename enable_if<!is_pointer<T>::value>::type
print(const T& t)
{
cout << t << endl;
}
int main()
{
foo(1);
foo(3.14); // foo(...)
int n = 10;
print(n);
print(&n);
}
- 함수 찾는 순서 ex) foo( 3.14f );
- exactly matching
- template
- promotion
- standard conversion
- user define conversion
- struct FLOAT { FLOAT(float) {} };
- void foo(FLOAT)
- variadic argument