如何理解C++11中的默认模板参数?针对示例的疑问解析
先贴出你提供的示例代码:
template <typename U, typename F=std::less<U>> int compare(const U& v1, const U& v2, F f = F()) { if (f(v1, v2)) return -1; if (f(v2, v1)) return 1; return 0; }
针对你对typename F=std::less<U>的疑问,逐一解答:
1. 为什么类型参数可以指定默认值?
这是C++模板的类型参数默认实参特性,和函数参数的默认值逻辑类似:当你实例化模板时,如果没有显式指定模板参数F,编译器会自动用std::less<U>作为F的类型。
比如compare(1,2)会被实例化为compare<int, std::less<int>>(1,2),函数参数f的默认值是std::less<int>()(即该类型的默认构造对象)。
2. 你提到的几种写法和它的区别
auto F = std::less<U>;:完全错误。auto用于推导变量的类型,而F是模板的类型参数(类型占位符),不是变量。而且std::less<U>是一个类型,不能直接赋值给变量,正确的变量声明应该是auto f = std::less<U>();(创建该类型的实例),但这和模板参数F的作用完全无关。typedef F std::less<U>:语法和逻辑都不对。typedef是给已有类型起别名,语法上应该是typedef std::less<U> F;,但这是在某个作用域内定义类型别名,无法用来设置模板参数的默认值——模板参数F是实例化时才确定的占位符,不是已存在的类型。using F = std::less<U>:可以类比理解,但本质不同。using是类型别名声明,而模板参数默认值是指定“未显式提供F时,F的类型就是std::less<U>”。当你省略F实例化模板时,编译器相当于自动为F绑定了std::less<U>类型,效果类似在模板内写了using F = std::less<U>,但这是模板参数机制的作用,不是普通的类型别名。
补充:这个模板的灵活用法
你可以显式指定自定义的比较器类型,或者直接传比较器对象让编译器推导类型:
// 自定义比较器类型:按大于比较 struct MyGreater { template <typename T> bool operator()(const T& a, const T& b) const { return a > b; } }; int main() { int x = 5, y = 3; // 显式指定F为MyGreater,使用自定义比较逻辑 compare<int, MyGreater>(x, y); // 传临时比较器对象,编译器自动推导F为MyGreater compare(x, y, MyGreater()); // 省略F,使用默认的std::less<int> compare(x, y); }
内容的提问来源于stack exchange,提问作者Yiqun Cui

