我在c++中做错了什么,泛型函数
What am i doing wrong in this code in C++ , Generic Functions?
我在c++中尝试了一个示例泛型函数,代码如下:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
template <typename T>
T max(T a, T b){
return (a>b)?a:b;
}
int main()
{
int a=2,b=4;
float af = 2.01,bf=2.012;
double ad = 2.11,bd=1.22;
cout<<max(a,b);
}
我得到的错误是
main.cpp: In function ‘int main()’:
main.cpp:20:18: error: call of overloaded ‘max(int&, int&)’ is ambiguous
cout<<max(a,b);
^
main.cpp:20:18: note: candidates are:
main.cpp:9:3: note: T max(T, T) [with T = int]
T max(T a, T b){
^main.cpp: In function ‘int main()’:
main.cpp:20:18: error: call of overloaded ‘max(int&, int&)’ is ambiguous
cout<<max(a,b);
^
main.cpp:20:18: note: candidates are:
main.cpp:9:3: note: T max(T, T) [with T = int]
T max(T a, T b){
^main.cpp: In function ‘int main()’:
main.cpp:20:18: error: call of overloaded ‘max(int&, int&)’ is ambiguous
cout<<max(a,b);
^
main.cpp:20:18: note: candidates are:
main.cpp:9:3: note: T max(T, T) [with T = int]
T max(T a, T b){
^
我哪里做错了?
重载max(int&, int&)
调用有二义性是什么意思?
为什么我得到它的参数显示为&
,而我上面没有定义这样的语法?
问题是c++已经有了一个std::max
定义。
再选一个名字,一切都会好起来的。
在c++中,using namespace std
方法是一个坏主意,因为将注入数千个名称。只要养成在标准名称前输入std::
的习惯就可以了。
还请记住,在编写时节省时间并不是那么重要,重要的是在读取时节省时间(通常代码只编写一次,但阅读和理解多次)。
标准名称前面的 std::
实际上加快了阅读速度,并让当场理解正在使用的是标准库的一部分(不是每个人都记住整个标准库)。
Skypjack和6502的答案非常正确,所以我在这里就不详述了。
同样值得注意的是,max
的标准版本并没有那么聪明。您可以使用以下代码使其不编译:
int main()
{
int a = 0;
double b = 1;
auto c = std::max(a, b);
}
产生错误消息:
16:错误:没有匹配的函数调用max(int&, double&)
如果我们想重写max,我们可以想象通过这样写来改进它:
#include <type_traits>
namespace notstd {
template <typename T1, class T2>
auto max_any(T1 a, T2 b) -> std::common_type_t<T1, T2>
{
return (a>b) ? a : b;
}
}
int main()
{
int a = 0;
double b = 1;
auto c = notstd::max_any(a, b);
}
但是当然会有一些后果。
首先,max_any
现在强制获取副本并(可能)执行转换。对于整数和双精度,这几乎不值得一提。
但是,如果T1和T2是具有适当转换操作符的两类对象,则对它们调用max_any
可能是一个代价昂贵的操作。它也可能有物质上的副作用。
std::max
是根据T&
类型的参数定义的。它强制调用者执行转换。事实证明,这不是std::max
的限制。这是一个安全功能。
该函数不会在代码中注入任何隐藏的副作用。
为了在其行为中保持"最不意外的路径",标准库有时要求其用户拼写出他们想要的意外行为。
令人惊讶的行为示例
这个程序可以完美地编译:
#include <cstdlib>
#include <iostream>
namespace notstd {
template <typename T1, class T2>
auto max_any(T1 a, T2 b)
{
return (b < a) ? a : b;
}
}
struct A {
A() = default;
};
struct B {
B() = default;
B (A const&) { std::exit(100); }
};
bool operator<(B const&, A const &) { return true; }
int main()
{
A a;
B b;
auto c = notstd::max_any(a, b);
std::cout << "Hello, Worldn";
}
但是它永远不会打印"Hello, World"
维护这段代码的人可能会惊讶地发现。
标准模板库中已经存在一个max
函数(即std::max
)。
使用using namespace
指令,您将从std::
命名空间导入到您正在使用声明本身的命名空间。
您仍然可以使用以下行来选择max
的实现:
cout << ::max(a,b);
否则,正如有人已经提到的,您可以为您的函数选择一个不同的名称,或者直接使用标准模板库中的名称。
- 链表的泛型函数remove()与成员函数remove)
- 以特征类型作为参数的泛型函数回调
- 传递非泛型函数的最有效方法是什么?
- 泛型函数反向打印任何矢量,编译器出错
- 是否可以在C++中创建泛型函数指针?
- 将泛型函数及其参数传递给元函数
- C++ 中的泛型函数持有者
- C++ 验证使泛型函数
- 两个不同流的泛型函数
- 如何覆盖 'const T&' 和 'T&&' 的泛型函数,其中 T 可以作为引用?
- 如何创建公开泛型函数的 DLL
- 为什么 std::apply 使用泛型函数失败
- 在某个值范围内生成 BST 的泛型函数
- 无法在循环中实例化泛型函数
- MISRA C++规则 14-5-1:在与类型关联的命名空间中声明的泛型函数模板的名称
- 使用泛型函数调用打印结构的所有嵌套成员变量
- C++ 使用数组作为参数创建泛型函数
- 泛型函数是否可以用于对结构求和
- C++为所有 std::sets 编写泛型函数
- 指向类成员函数的泛型函数指针