首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么MSVC不喜欢非模板重载函数而不是模板重载函数?

MSVC(Microsoft Visual C++)是微软的C++编译器,它在处理函数重载时有一些特殊的行为。在MSVC中,当存在非模板重载函数和模板重载函数时,它更倾向于选择模板重载函数。

这种偏好的原因主要有以下几点:

  1. 模板重载函数具有更高的通用性:模板函数可以根据不同的参数类型进行实例化,从而适应更广泛的使用场景。相比之下,非模板函数只能针对特定的参数类型进行重载,因此其适用范围相对较窄。
  2. 模板重载函数可以提供更好的代码复用:通过使用模板,可以将相似的代码逻辑抽象为通用的函数模板,从而避免了重复编写类似的非模板函数。这样可以提高代码的可维护性和可扩展性。
  3. 模板重载函数可以更好地支持泛型编程:C++的模板机制是实现泛型编程的重要手段,通过模板重载函数可以实现对不同类型的参数进行统一的处理。这在一些需要处理多种数据类型的场景下非常有用。

需要注意的是,MSVC的这种偏好并不意味着非模板重载函数是不被支持的或者不推荐的。在实际开发中,根据具体的需求和场景选择合适的函数重载方式是很重要的。同时,不同的编译器可能对函数重载的处理方式有所差异,因此在跨平台开发时需要注意编译器的兼容性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

从零开始学C++之模板(一):函数模板函数模板特化、重载函数模板模板函数重载

函数模板不是函数,不能被执行 置换代码中的类型参数得到模板函数——实例化 实例化后的模板函数是真正的函数,可以被执行 3、模板被编译了两次 实例化之前,先检查模板代码本身,查看语法是否正确;...: const char* str1 = "aaa"; const char* str2 = "zzz"; 此时如果按一般的实例化,比较的将是str1 和 str2 的大小,即比较指针数值大小,不是字符串大小...b : a; } (四)、重载函数模板模板函数重载 C++语言可以重载一个函数模板 用户可以用模板函数重载一个同名的函数模板 max.h: #ifndef _MAX_H_ #define...c : ::max(a, b);     // ::max 会调用模板函数 } // 模板函数重载 const int &max(const int &a, const int &b) {     ...b : a; } // 模板函数重载 const char *const &max(const char *const &a, const char *const &b) {     cout <<

1.8K00

函数模板与同名的模板函数不可以重载(重载的定义)

关于函数重载机制,是一个比较复杂的问题,其中涉及到了优先级定义和最佳匹配等问题,如果要阐述清楚,恐怕不是一两篇文章就能说的明白。...当其它的要素都相等时,重载机制将优先选择调用函数模板不是函数模板【对于这个问题,个人觉得可能是基于如下的原因:进行重载将降低程序的效率,对函数模板是如此,对于更为复杂的函数模板更是如此(至少还需进行一次实例化...),因此重载机制将优先选择调用函数模板不是函数模板。】。...那些无法跟函数模板进行最佳匹配的,则调用函数模板的实例化对象,如第一和第二个函数调用。...只适用于一般函数(即函数模板)。

83820

函数模板遇上函数重载

函数模板和普通函数区别 函数模板不允许自动类型转化 普通函数能够进行自动类型转换 函数模板和普通函数在一起,调用规则: 函数模板可以像普通函数一样被重载 C++编译器优先考虑普通函数 如果函数模板可以产生一个更好的匹配...myswap(T &a, T &b) { T t; t = a; a = b; b = t; cout<<"myswap 模板函数do"<<endl; } void myswap(char...endl; return Max(Max(a, b), c); } void main() { int a = 1; int b = 2; cout<<Max(a, b)<<endl; //当函数模板和普通函数都符合调用时...,优先选择普通函数 cout(a, b) 类型列表 cout<<Max(3.0, 4.0)<<endl; //如果 函数模板产生更好的匹配...使用函数模板 cout<<Max(5.0, 6.0, 7.0)<<endl; //重载 cout<<Max('a', 100)<<endl; //调用普通函数 可以隐式类型转换 system

82910

C++函数内置、函数重载函数模板

C++内置函数 C++提供一种可以提高效率的方法,在编译时将所调用函数的代码直接嵌入到主调函数中,不是将流程转出去,这种函数称为C++的内置函数。...虽然使用内置函数可以节省运行时间,但却增加了目标程序的长度,因此一般只将规模很小而使用频繁的函数声明为内置函数。 读者需要知道一点,内置函数中不能包括复杂的控制语句,如循环语句和switch。...C++函数重载 C++允许用同一函数名定义多个函数,这些函数的参数个数和参数类型不同,即对一个函数名重新赋予新的含义,使一个函数名可以多用,这就是函数重载。...函数模板,实际上就是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。...、函数重载函数模板 更多案例可以go公众号:C语言入门到精通

7163028

C++11:利用模板简化重载右值引用参数的函数

左值引用版本和右值引用版本的函数 下面是matrix_cl类的两个重载的构造函数,这两个构造函数除了最后一个参数不同,其他的参数都完全一样,只有最后一个参数不同(分别为右值和左值引用)。...如果最后一个参数不是右值引用,则会调用第二个函数(左值引用版本),这时this->v=lv;调用的是std::vector的复制赋值操作符 vector&operator=(vector&),这样,this...上面的例子中构造函数只有3行,还好办,如果构造函数有30行甚至更多的代码,我们岂不是要把这些代码几乎原样复制两个版本?...如果真是这样的话,这代码的就太臃肿了,可维护性也不好啊,能不能将两个函数合并为一个? yes!we can 如果要把上面两个函数合并为一个就要用到模板编程了。 下面是合并后的代码。...std::move(v):v; }; 有了_ENABLE进行参数类型限制,在类中有多个类型的模板构造函数的情况,调用构造函数时就不会将别的类型的参数误传入,产生编译错误。

82510

【C++】泛型编程 ⑨ ( 类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 )

模板函数声明 与 函数实现 都写在同一个类中 ; 类模板函数实现 在 类外部进行 , 写在相同的 .h 和 .cpp 源码文件中 ; 类模板函数实现 在 类外部进行 , 写在不同的...template 类型参数列表声明 , 使用域作用符 Father:: 访问函数 ; 3、函数声明与函数实现分离 + 友元函数引入 如果要在 类模板 中进行运算符重载..., 就需要用到友元函数 ; 如果将 类模板函数实现 , 定义在函数外部 , 结合 友元函数 使用 , 就变得很复杂 , 下面针对该问题进行讨论 ; 二、普通类的运算符重载 - 函数声明 和 函数实现...三、类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 1、类模板 的 外部友元函数问题 将上述 " 普通类的运算符重载 - 函数声明 和 函数实现 写在同一个类中 " 示例改造成 类模板...template 就是重新定义了一个新的泛型 , 与 类模板 中的 T 不是同一个泛型类型 ; 解决上述问题 , 就需要将 友元函数 定义在 类模板 的内部 ; template

17710

C++11:模板实现opencl向量类型的简单运算符重载及length,distance函数

如果能像模板内核代码一样,为向量运算符提供简单的向量运算功能,就可以大大简化这些代码。 利用C++的模板计算函数,可以实现上面的功能。...{ RET r; r.hi = p1.hi - p2; r.lo = p1.lo - p2; return r; } /* * (递归结束)向量减法操作符,第一个操作数向量...(实现其他的运算符和函数也是差不多的代码,因为我暂时不需要就没有继续写下去)。...代码开始有两个很长的模板函数cl_vector_type和is_cl_vector,所有的其他函数模板都要用到这两个模板函数: cl_vector_type用于构造一个指定元素类型和长度的opencl...有了这些模板函数的支持,主机端opencl向量的运算就变得像在内核代码中一样简单,还以前面的例子用模板函数重写,就是这样: cl_int4 p1={4,2,0,9}; cl_int4 p2={3,9,-

1.7K10

【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 )

( 类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 ) 实现了第一种情况 , 类模板函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码...T> class Student { public: Student(T x, T y); } 2、类模板 外部 实现 普通函数 将 类内部的 普通函数 实现 加法运算符重载函数 , 提取到 类模板...友元函数 不是 类中的函数 , 是 类外部的函数 , 友元函数 中又用到了 泛型 T , 说明这是一个 模板函数 ; 友元函数 是 全局函数 , 不属于 类模板 , 不要使用 域操作符 访问友元函数...重载 左移 右移 操作符时 , 才使用 友元函数 ; ( 1 ) 错误示例及分析 - 类模板 的 外部友元函数 二次编译 问题 在 类模板 内部声明 友元函数 , template <typename...( 2 ) 正确写法 友元函数 不要乱用 , 只有在 重载 左移 右移 操作符时 , 才使用 友元函数 ; 这是 函数模板 二次编译 问题 , 一般情况下 , 函数模板 只有在 调用时 , 才需要将

15210

Google C++ 编程风格指南(五):其他 C++ 特性

例如,用 AppendString() 和 AppendInt() 等, 不是一口气重载多个 Append(). 5.4. 缺省参数 我们不允许使用缺省函数参数,少数极端情况除外。...尽可能改用函数重载。 优点: 当您有依赖缺省参数的函数时,您也许偶尔会修改修改这些缺省参数。通过缺省参数,不用再为个别情况特意定义一大堆函数了。...函数重载正好相反,毕竟它们所谓的「缺省参数」只会出现在函数定义里。 结论: 由于缺点并不是很严重,有些人依旧偏爱缺省参数胜于函数重载。...如果 i 是迭代器或其他数值类型, 拷贝的代价是比较大的. 既然两种自增方式实现的功能一样, 为什么不总是使用前置自增呢?...因此, 使用断言来指出变量为负数, 不是使用无符号型! 5.15. 64 位下的可移植性 代码应该对 64 位和 32 位系统友好.

1.1K30

C++20初体验——concepts

这当然不是让我们来重载这个运算符。 STL源码可以提供一些帮助: /** * @brief Sort the elements of a sequence....如果模板参数代入时出现了不存在的类型或变量,该约束仅仅是不被满足,不会产生编译错误。 约束可以用于函数模板、类模板和成员函数模板类的模板成员函数除外。...函数模板与类模板的约束是类似的,只有满足约束时模板才能实例化;对于成员函数的约束,如果它作用于模板类的模板参数,当约束不满足时,并不是模板不能被实例化,而是实例化后的模板类没有这个成员函数: #include...包含关系作用在由&&和||连接的逻辑表达式上(实际上是合取与析取),通过深入到判断两个原子的(不是&&或||连接的)表达式是否相同从而决定包含关系,只有相同的concept加上相同的模板参数才是相同,...的表达式也都得出现,不能像上面的concept实现那样利用两个函数之间由重载优先级建立起的层次关系。与上一节相比,这里的代码重复更恶心一点。

1.3K10

【C++系列(合集)】特性多又复杂?不存在!——这篇C++大全直接干碎(超级大全,精讲)

答案:不是的,要修改成员变量的函数不能加。 三.几个的使用场景 请思考下面的几个问题: 1. const对象可以调用const成员函数吗?no 2....,有返回值的目的是为了支持连续赋值) 检测是否可以自己给自己赋值 返回*this:(对this指针解引用,要符合连续赋值的含义) 赋值运算符只能重载成为类的成员函数不能重载成全局函数(如果重载成全局函数...一个模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个模板函数 对于模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用模板函数不会从该模 板产生出一个实例... 中即可,类模板名字不是真正的类,实例化的结果才是真正的类。...需要加模板参数列表;在访问类模板时,要用Vector(类型),不是Vector(类名) 代码演示: template class Vector { public :

13110

【C++】泛型编程——模板初阶

这样就不行了,为什么呢? 因为这时候函数模板在推演实例化的时候会出现歧义: 该语句不能通过编译,因为在编译期间,该函数模板实例化时,需要推演其实参类型。...为什么会调第一个,因为编译器在这个地方也会看调哪一个成本会更低一点,第一个呢可以直接调,但第二个的话是不是还要用模板实例化之后才能调啊。 所以在这里编译器选择了第一个。...另外: 对于模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用模板函数不会从该模板产生出一个实例。 但如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。...我们看到这里调用了两个参数的模板函数生成的更加匹配的Add函数。 首先大家要知道这里其实第一个模板函数也是可以调的,普通函数是可以进行自动类型转换的,模板函数是不会自动类型转换的。...但是当前这种情况要调模板函数毕竟还得进行一个类型转换,而我们得第二个函数模板有两个参数T1和T2,那调用的时候模板不是可以产生一个具有更好匹配的函数

11110

【C++】泛型编程 ⑪ ( 类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 )

将 类模板 函数声明 与 函数实现 分开进行编码 , 有 三种 方式 : 类模板函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码 ; 类模板函数实现 在 类外部进行 ,...类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 ) 中实现了第一种情况 , 类模板函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码...; 在博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 ) 中 , 分析了 第二种情况 , 类模板 的...; 一、类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 1、分离代码 后的 友元函数报错信息 - 错误示例 上一篇博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载...- 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 ) 中 , 分析了 第二种情况 , 类模板函数实现 在 类外部进行 , 写在 一个 cpp 源码文件中

17210

C++ 模板沉思录(上)

1.4 惰性实例化 函数模板不是函数,而是一个可以生成函数的语法组分;同理,类模板不是类,而是一个可以生成类的语法组分。我们称通过函数模板生成函数,或通过类模板生成类的过程为模板实例化。...那么,为什么不直接使用形如“T()”这样的写法,需要声明一个“稻草人函数”呢?...我想,不用我说你就已经明白原因了:这是因为并不是所有的T都具有默认构造函数如果T没有默认构造函数,那么“T()”就是错误的。...接下来是最关键的部分,我们声明了一对重载函数,这两个函数的区别有二: 返回值不同,一个是sizeof的结果为1的值,另一个是sizeof的结果为2的值 形参不同,一个是B,一个是“...”...”进行调用(不是认为这个“根本无法被生成出来”的模板是一个错误)。

1.3K20

C++:19---重载模板模板特例化

一、重载模板 函数模板可以被另一个模板或一个普通模板函数重载 如果涉及函数模板,则函数匹配规则会有以下的约束: 如果同样好的函数中只有一个是非模板函数,则选择此函数 如果同样好的函数中没有模板函数...,代码将编译失败,但对于重载函数模板函数而言,则不是这样。...定义函数模板特例化 为了处理字符指针(不是数组),可以为第一个版本的compare定义一个模板特例化版本。...但是如果我们将一个特殊的函数定义为一个特例化版本还是一个独立的模板函数,会影响到函数匹配(例如我们在上面在上面定义的3个compare函数,其中两个是模板,一个是非模板,那么模板的将与模板函数构成重载...我们可以之特例化特定成员函数不是特例化整个模板 例如,如果Foo是一个模板,包含一个成员Bar,我们可以只特例化该成员: //下面是一个模板类templatestruct Foo

1.3K20

【C++】STL---list

++,因为它们的空间不是连续的,所以我们要把 list 迭代器封装成一个类。...,其参数有三个,分别是类型、类型的引用(const 和 const) 、类型的指针(const 和 const) ; 为什么要定义三个模板参数呢,因为考虑到 const 迭代器,const 迭代器和普通迭代器不是同一个类...+it,只是期望迭代器指向的内容不能被修改,如 *it = 10、it->10 ; 这就类比 const T* 和 T* const , const T* 中 const 是修饰指向的内容不能被修改,..._node == _node; } (5)* 解引用重载 和 -> 重载 解引用重载 和 -> 重载 就是改变迭代器指向内容的两个运算符,所以我们定义的三个模板参数,就在这里起作用了;比如我们实例化的模板参数是...)和 Ptr(箭头重载) 作返回值; 如果是 const 迭代器的 __list_iterator,T& 就是 Ref,T* 就是 Ptr;所以就可以根据它们的类型返回对应的迭代器类型

4710

【C++】侯捷C++面向对象高级编程(下)

但是第二个OK 这个不是模板模板参数 调用中我们使用第二种方法,指明第二模板参数,其实这个list就已经不是模板了,已经指明了,即使它是用模板设计出来的东西。...所以temp>第二个参数,不是模板模板参数。...析构——由外内 子类析构时,会先析构掉自己执行完后,然后指定父类的默认析构函数,同样由编译器添加并执行。...析构——由外内 同上,要注意的是,上面先构造的,会后析构。 ---- 虚指针与虚函数表(vptr & vtbl) 虚指针指向虚函数表,虚函数表中都是函数指针。...常量对象不能调用非常量成员函数,反之,可以。 但是,当成员函数的const版本和const版本都存在,则常量对象只能调用const版本,const对象只能调用const版本。

60520

C++进阶之路:何为命名空间、缺省参数与函数重载

缺省参数的值必须在函数声明时指定,不能在函数定义时指定。...仅返回类型不同不足以区分重载函数 隐藏名称:如果一个函数在某个作用域内被声明(但不是定义),那么具有相同名称但在不同作用域内的函数可能不会被考虑用于重载。这被称为“名称隐藏”。...例如,void foo(int*)和void foo(int&)是两个不同的重载函数函数模板函数模板也可以与常规函数重载。...然而,函数模板通常被视为更一般的解决方案,因为它们可以处理多种类型,不仅仅是预先定义的类型列表。...const和const参数:对于指针或引用参数,指向const和const的指针或引用是不同的,可以用于重载

7310

模板

泛型 c++中引进了泛型的概念,引用泛型也是为了解决了C语言中对不同类型的参数需要实现多个不同参数的麻烦。 泛型只是提供一个模板而已,对于不同的函数或者类会自动实例化相应的函数或者类。...模板 模板分为函数模板和类模板函数模板 基本语法: template,typename也可以换成class,T可以随便改变,不叫T也是可以的。...对于c语言的函数,我们需要写不同类型的参数。即使c++中引入了函数重载,也是需要写多个重载函数模板的出现解决了这个问题。...类模板 为什么引用模板上文已经说了,这里就不再叙述。 本博主觉得和函数模板差别不是很大,只不过要显示的写出类型。类型随意,可以是自定义类型也可以为内置类型。...我们想的是即使传的是地址也能进行比较,不是对地址进行比较。 下面这样就可以了。

43210

C++初阶-模板初阶

重载函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数 代码的可维护性比较低,一个出错可能所有的重载均出错 引入: C++为了解决这样的问题,采用模板让编译器根据不同的类型利用该模子来生成相对应参数需要的函数代码...,也可以使用class(切记:不能使用struct代替class) 2、函数模板原理 函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具,所以其实模板就是将本来应该我们做的重复的事情交给了编译器...一个模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个模板函数 示例: // 专门处理int的加法函数 int Add(int left, int right) { return...() { Add(1, 2); // 与模板函数匹配,编译器不需要特化 Add(1, 2); // 调用编译器特化的Add版本 } 对于模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用模板函数不会从该模板产生出一个实例...= 0; } 2、类模板实例化 类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟,然后将实例化的类型放在中即可,类模板名字不是真正的类,实例化的结果才是真正的类 示例

42330
领券