按值和按引用差异的函数模板
function template by value and by reference difference
我正在遵循本教程 - http://www.learncpp.com/cpp-tutorial/132-function-template-instances/
// passing all parameters by references
template <typename T1, typename T2>
const T2& add_two_objects(const T1& x,const T2& y) {
return x+y;
};
int main() {
using std::cout;
int x(0),y(0);
std::cout << "Please enter number 1" << std::endl;
std::cin >> x;
std::cout << "Please enter number 2" << std::endl;
std::cin >> y;
cout<< "sum of two integers is " << add_two_objects(x,y+1.2) << 'n';
cout<< "sum of two double is " << add_two_objects(x,y+2.52424324) << 'n';
return 0;
}
程序编译良好,但在运行时,我总是遇到分段错误。但是,如果我将模板更改为按值传递,那么一切正常。
// passing all parameters by value
template <typename T1, typename T2>
const T2 add_two_objects(const T1 x,const T2 y) {
return x+y;
};
谁能解释一下?
template <typename T1, typename T2>
const T2& add_two_objects(const T1& x, const T2& y) {
return x+y;
};
返回对临时的引用。使返回值
template <typename T1, typename T2>
T2 add_two_objects(const T1& x, const T2& y) {
return x+y;
};
你应该没事。
顺便说一句,目前尚不清楚返回T2
是这里最好的选择。例如,考虑案例T1=size_t
和T2=char
。最好返回操作x+y
实际生成的类型
template <typename T1, typename T2>
auto add_two_objects(const T1& x, const T2& y)
-> decltype(x+y)
{
return x+y;
};
------编辑-----
不得返回对临时对象的引用。这是一个错误。如果你想要一个错误,那就去做吧。而且你不应该使用糟糕的教程。在某些情况下,您希望/应该返回引用,但这不是其中之一。这些是当引用是指向一个对象时,该对象在从函数返回时不会被销毁(或超出范围((因为所有自动和临时变量都会如此(。
为了更清楚,让我们将整数包装在结构中。
这是一个演示程序
#include <iostream>
struct A
{
A( int x ) : x( x ) {}
~A() { std::cout << "[A::~A() is called for x = " << x << ']' << std::endl; }
int x;
};
A operator +( const A &lhs, const A &rhs )
{
return A( lhs.x + rhs.x );
}
std::ostream & operator <<( std::ostream &os, const A &a )
{
return os << a.x;
}
template <typename T1, typename T2>
const T2& add_two_objects(const T1& x,const T2& y) {
return x+y;
};
int main()
{
std::cout<< "sum of two integers is " << add_two_objects( A( 1 ), A( 2 ) ) << 'n';
return 0;
}
它的输出可能看起来像
prog.cc:22:18: warning: returning reference to temporary [-Wreturn-local-addr]
return x+y;
^
sum of two integers is [A::~A() is called for x = 3]
Segmentation fault
首先,编译器警告该函数返回对临时值的引用。也就是说,在退出函数后,临时对象将被销毁,并且此输出
[A::~A() is called for x = 3]
证实了这一点。
因此,引用将无效,并且程序具有未定义的行为。
实际上,您可以通过以下方式想象程序逻辑
int main()
{
const A &r = add_two_objects( A( 1 ), A( 2 ) );
std::cout<< "sum of two integers is " << r << 'n';
return 0;
}
它的输出看起来与上述程序几乎相似
prog.cc:22:18: warning: returning reference to temporary [-Wreturn-local-addr]
return x+y;
^
[A::~A() is called for x = 3]
[A::~A() is called for x = 1]
[A::~A() is called for x = 2]
Segmentation fault
也就是说,引用变得无效。
如果删除函数声明中的引用
template <typename T1, typename T2>
const T2/*&*/ add_two_objects(const T1& x,const T2& y) {
return x+y;
};
那么程序输出可能看起来像
sum of two integers is 3
[A::~A() is called for x = 3]
[A::~A() is called for x = 1]
[A::~A() is called for x = 2]
相关文章:
- 具有常量引用参数的函数模板专用化
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 两个函数模板候选项.将一个参数作为引用后,选择不太专业的模板
- 请参阅在 Visual Studio 2019 中捕获 std::exception 时对函数模板实例化消息的引用
- 为什么 std::函数模板构造函数不使用通用引用?
- 按值和按引用差异的函数模板
- 如何声明接受转发引用并返回引用或副本的函数模板
- 链接器错误,未定义对模板化构造函数的引用
- C++非类型模板模板到函数指针/引用
- 对模板函数的引用向量
- 定义重载C++函数模板的原型时,使用其名称引用以前的定义是否合法?
- 专门化采用通用引用参数的函数模板
- C++ 中的函数模板专用化和右值引用
- C++类模板构造函数 -- 重载引用 (U&) 与数组 (U*) 失败
- VS2013无法根据模板参数指定具有通用引用和返回类型的函数模板
- 具有通用引用的成员函数模板不接受左值
- 在具有通用引用参数的函数模板中使用类模板
- 是否可以使函数模板从函数引用中获取“decltype”
- 返回对函数模板的引用
- 在 c++11 中,当参数类型为常量左值引用与非常量左值引用时,函数模板类型推导的工作原理