CTTCG 20 Overloading on Type Properties
TLDR:几种 SFINAE 的模式
- 对于函数参数列表非空的函数模板,可以用非 varargs 函数实现功能,varargs 作为 fallback。
- 类模板可以用偏特化实现功能重载,用带模板默认参数的原始模板作为 fallback。
- 模板用 tag dispatching 不会有重复定义的问题。
std::enable_if
用在函数模板的模板默认参数上表达更简洁,但用在返回值上可避免重复定义。对比起来,类模板虽然能支持偏特化,但是也没有用返回值 SFINAE 避免重复的好处。(不过 C++20 有了 requires 就无所谓了。)- concept、constexpr if 等。
1 和 2 其实分别适应了函数模板和类模板的特点:函数模板不能偏特化,类模板不是函数因而不能使用 varargs。
几个难点:
- 找不到能匹配的函数:需要设计 fallback。
- 找到了多个能匹配且优先级不能区分的函数(ambiguous):需要设计互斥条件。
- 重复定义同一模板(只有模板默认参数不同):
std::enable_if
使用不当。可以再增加一个默认参数缓解问题,或者把std::enable_if
放在返回值位置上。