【问题标题】:Template use without angle brackets - Overloading?没有尖括号的模板使用 - 重载?
【发布时间】:2021-11-06 01:48:00
【问题描述】:

我对使用template<> 括号和不使用它们的想法有点困惑。当我编译代码时,我得到了我没有预料到的输出,并且没有弄清楚为什么。

例如,假设我有 2 个函数和一个具有相同原型的 template

using namespace std;

template<typename T> void copy(T a, T b)
{
    cout << "template copy" << endl;
}
void copy(int a, int b)
{
    cout << "int copy" << endl;
}
void copy(string a, string b)
{
    cout << "string copy" << endl;
}

以及编译main函数后:

int main()
{
    copy<int>(1, 2);
    copy<string>("ha", "ha");
    copy("ab", "bc");
    copy(1, 2);
    
    return 0;
}

输出如下所示:

template copy
template copy
template copy
int copy

为了记录,所有代码都写在同一个 CPP 文件中。

【问题讨论】:

  • 你的代码很糟糕......查看Why is "using namespace std;" considered bad practice?并考虑std::copy
  • 编译器将首先选择具有最佳/最显式匹配签名的函数。因此对于字符串和整数,它将首先选择非模板版本。在您的字符串(数字 3)的情况下,它将为 char 数组选择一个模板。
  • 第三次调用copy正在使用copy&lt;const char*&gt;
  • 对于说我的代码不好的人,这是我在在线编译器上制作的一个简单的快速代码,试图理解这篇文章的问题,当我编码时我不使用 std,我知道这是一个坏习惯:)
  • 请注意,void copy(int, int) 不是 template &lt;typename T&gt;void copy(T, T) 的特化。

标签: c++ templates overload-resolution


【解决方案1】:

您必须记住,文字字符串实际上是(常量)字符数组,它衰减为指向char 的(常量)指针,即const char*

由于您的函数采用std::string 参数不是直接匹配,并且编译器不会进行转换,因此将使用模板重载(如copy&lt;const char*&gt;)。

【讨论】:

【解决方案2】:

在这些电话中

copy<int>(1, 2);
copy<string>("ha", "ha");

您明确指定了模板参数。所以编译器只会考虑模板函数。

在本次通话中

copy("ab", "bc");

您没有指定模板参数。所以编译器会考虑所有名称为copy的重载函数,并选择最可行的函数。

表示字符串字面量的参数类型是const char [3]

由于标准转换顺序,参数被显式转换为指向const char *类型字符串文字的第一个字符的指针。

所以编译器可以推断出模板参数的类型为const char *

调用非模板函数

void copy(string a, string b)
{
    cout << "string copy" << endl;
}

编译器需要再使用一次转换(用户定义的转换)来将指针转换为std::string类型的对象。

因此模板函数需要较少的转换,因此编译器认为它更合适。结果你得到了输出

template copy

这是一个演示程序。

#include <iostream>
#include <iomanip>
#include <type_traits>

template <typename T>
void f( T , T )
{
    std::cout << std::boolalpha << std::is_same<T, const char *>::value << '\n';
}

int main() 
{
    f( "ab", "bc" );
    
    return 0;
}

程序输出是

true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-14
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多