繁体   English   中英

C ++函数模板:参数类型和返回类型必须使用&吗?

[英]C++ function template: Must use & for argument type and return type?

我正在学习使用功能模板。 我发现,如果我将参数类型声明为引用,则程序将运行。 但是,如果参数类型不是引用,则会出错。 例如:

下面的代码打印正确的结果,并且没有错误。

#include <iostream>
using namespace std;

template <typename T>
T & max (T & a, T & b){
    return a>b?a:b;
}

int main(int argc, char const *argv[])
{
    cout << max(1,2) << endl;
    return 0;
}

但是,如果我删除了代码中的所有“ & ”,即如下更改上述程序:

#include <iostream>
using namespace std;

template <typename T>
T  max (T  a, T  b){
    return a>b?a:b;
}

int main(int argc, char const *argv[])
{
    cout << max(1,2) << endl;
    return 0;
}

此代码将导致以下错误。

a.cpp: In function ‘int main(int, const char**)’:
a.cpp:11:17: error: call of overloaded ‘max(int, int)’ is ambiguous
  cout << max(1,2) << endl;
                 ^
a.cpp:5:4: note: candidate: T max(T, T) [with T = int]
 T  max (T  a, T  b){
    ^~~
In file included from /usr/include/c++/7/bits/char_traits.h:39:0,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from a.cpp:1:
/usr/include/c++/7/bits/stl_algobase.h:219:5: note: candidate: constexpr const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
     max(const _Tp& __a, const _Tp& __b)

为什么? 谢谢大家的帮助!

在第一个示例中不考虑引用参数版本,因为这些常量不适合可修改的左值引用。 还要感谢using namespace std;的不当建议using namespace std; ,您可以改用std版,它将起作用。 您可以在第一个版本中删除您的max代码,并且该代码仍然可以使用,因为一旦这些引用触发取消资格,就不会考虑该代码。

总之,第一个版本不考虑你的max的代码,因为它不符合,那么std::max来代替(这符合资格)。 在第二个版本中,使用值参数的代码和使用const-references的std::max版本都可以使用,因此结果含糊不清。

在std名称空间中已定义具有相同(或兼容)名称和参数类型的函数(模板)。

去掉

using namespace std;

并在cout和endl前面加上std :::

std::cout << max(1,2) << std::endl;

否则,您将用std名称空间中的所有名称污染全局名称空间。

有一个模板化的max()函数可以接受名称空间std参数(在标准标头<algorithm> )。 尽管该标准不要求#include <iostream>引入该功能,但也不禁止该功能。 您的标准编译器确实通过<iostream>对其进行了介绍。

using指令( using namespace std )使std::max()模板被视为代码中匹配函数的候选对象。

在您的第一个代码示例中,调用max(1,2)std::max()相匹配,因为它接受const引用,并且比接受非const引用的函数更好。 它恰好产生您期望的输出。

在您的第二个代码示例中,按值传递,编译器没有理由偏爱您的max()std的一个(按值传递或按const引用传递对于传递像12这样的int常量都同样有效) 。 因此,编译器抱怨模棱两可。

问题在于:使用不同的编译器(或其标准库),您的代码可能会以不同的方式失败,因为不需要<iostream>声明std::max() ,并且并非所有实现都可以。

删除using指令,您的代码中std::max()的潜在用法将消失-在任何一个代码示例中, std::max()都不会被视为候选。 您的第一个示例将无法编译,因为不能使用非const引用来传递文字值。 第二个将编译并产生您期望的输出。 在符合标准的C ++编译器之间,此行为将是一致的(并且不影响诸如<iostream>类的标准头文件是否声明std::max() )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM