使用模板和不使用模板制作功能会产生不同的结果?

问题描述 投票:0回答:1

我写了这段代码:

#include <iostream>

void test(std::string && x) {
    std::cout << "test: 1" << std::endl;
}
void test(const std::string & x) {
    std::cout << "test: 2" << std::endl;
}
template<typename T>
void test2(T&& x) {
    std::cout << "test2: 1" << std::endl;
}
template<typename T>
void test2(const T & x) {
    std::cout << "test2: 2" << std::endl;
}
int main()
{
    std::string x = "aaa";
    std::string & y = x;
    test(y);
    test2(y);
    return 0;
}

它有4个功能,两个名为

test
和两个
test2
test2
由模板选择参数,
test
静态。两种类型都有一种用于
const T & x
的重载和一种用于
T && x
的重载。但是如果我用
T &
称呼它们,就会调用不同的类型。上面代码的结果是:

test: 2
test2: 1

如何,更重要的是,为什么会发生这种情况?

c++ templates overloading
1个回答
0
投票

粗略地说,编译器更喜欢涉及“更简单”类型转换的函数重载。

由于无法将左值引用转换为右值引用,因此函数

void test(std::string &&x);
根本无法调用,但是从
std::string&
const std::string&
的转换是可以的。这就是为什么你在调用
test
时得到“2”的原因。

模板案例不同,因为它也涉及到类型推导。

T&& x
是一个“通用引用”,它可以绑定任何东西,所以它不涉及任何类型转换。即当推导
T
时,函数
test2(T &&x)
变为
test2(std::string &x)
,完美匹配并且不需要类型转换。

另一方面,

test2(const T& x)
变成
test2(const std::string &x)
,需要1次类型转换,所以不如第一次重载有利。

© www.soinside.com 2019 - 2024. All rights reserved.