C++ 按值和按引用差异列出的函数模板

C++ 按值和按引用差异列出的函数模板,c++,reference,temporary-objects,C++,Reference,Temporary Objects,我正在学习本教程- //通过引用传递所有参数 模板 常数T2&添加两个对象(常数T1&x、常数T2&y){ 返回x+y; }; int main(){ 使用std::cout; int x(0),y(0); std::cout x; std::cout y; 不能 ------编辑----- 不能返回对临时对象的引用。这是一个错误。如果你想要一个错误,就去吧。你不应该使用糟糕的教程。有些情况下,你想要/应该返回一个引用,但这不是其中之一。当引用指向一个不会被销毁的对象时(或超出范围)返回函数时(

我正在学习本教程-

//通过引用传递所有参数
模板
常数T2&添加两个对象(常数T1&x、常数T2&y){
返回x+y;
};
int main(){
使用std::cout;
int x(0),y(0);
std::cout x;
std::cout y;
不能

------编辑-----

不能返回对临时对象的引用。这是一个错误。如果你想要一个错误,就去吧。你不应该使用糟糕的教程。有些情况下,你想要/应该返回一个引用,但这不是其中之一。当引用指向一个不会被销毁的对象时(或超出范围)返回函数时(所有自动和临时变量都将如此)。

template <typename T1, typename T2>
const T2& add_two_objects(const T1& x, const T2& 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;
                  ^
[A::~A() is called for x = 3]
[A::~A() is called for x = 1]
[A::~A() is called for x = 2]
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;
}
也就是说,引用变为无效

如果要删除函数声明中的引用

template <typename T1, typename T2>
const T2/*&*/ add_two_objects(const T1& x,const T2& 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;
                  ^
[A::~A() is called for x = 3]
[A::~A() is called for x = 1]
[A::~A() is called for x = 2]
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;
}
也就是说,引用变为无效

如果要删除函数声明中的引用

template <typename T1, typename T2>
const T2/*&*/ add_two_objects(const T1& x,const T2& y) {
        return x+y;
};

你不能返回对临时文件的引用。但这是毫无意义的代码,而且写得很糟糕。也许你应该找一个不同的教程?@CodyGray至少turial有一个
使用std::cout
而不是
使用namespace std;
我修改了教程示例以尝试更复杂的东西(当然要理解)我认为这个教程很好。你不能返回一个临时的引用。但是这是一个毫无意义的代码,而且写得很糟糕。也许你应该找一个不同的教程?@CodyGray至少这个教程有一个
使用std::cout
而不是
使用namespace std;
我修改了教程的例子来尝试complexer的东西(当然要理解)我认为教程很好。但是我想返回一个引用,而不是第一个解决方案所建议的值。这是否意味着教程代码是错误的?@infocombled您想返回一个对什么的引用?对方法范围内的变量的引用在方法范围外是无用的好吧,我有你的建议现在我明白了。如果我实例化一个静态对象,那么引用就不再指向临时对象。因此,我可以在函数模板中声明一个静态变量(static T2 z;),而不是返回(x+y);然后返回引用(z=x+y;返回z;)。当然,这不是一个真正的代码,只是为了了解基本知识。但我希望返回一个引用,而不是第一个解决方案建议的值。这是否意味着教程代码错误?@infocloubled您希望返回对什么的引用?对方法范围内的变量的引用在方法的范围好的,我现在已经理解了。如果我实例化一个静态对象,那么引用就不再指向临时对象。因此,我可以在函数模板中声明一个静态变量(static T2 z;),然后返回引用(z=x+y;返回z;)。当然,这不是一个真正的代码,只是为了理解基本知识。是否有任何特定原因导致结构出现警告,而不是
int
s?@tobi303原因可能是结构具有构造函数和析构函数。是否有任何特定原因导致结构出现警告,而不是
int
s?@tobi303原因可能是该结构具有构造函数和析构函数。
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]