C ++编译器,通过引用强制传递

时间:2019-09-23 09:55:04

标签: c++ reference parameter-passing default

是否可以将C ++编译器默认设置为将所有传递的参数解释为按引用定义新的修饰符,以指定您需要通过副本进行传递。

编程时,我发现仅需要我就需要通过副本传递数据,因此,至少对我而言,拥有“默认引用”更为有效

2 个答案:

答案 0 :(得分:3)

不仅没有这样的功能,永远不会有。这样做会导致定义明确的程序格式错误或性能更差,并且行为不确定。

考虑这个简单的格式正确的程序:

struct X {};

auto bar(X x) -> decltype(x)
{
    return x;
}

auto test()
{
    bar(X{});
}

您将如何改变它?没有办法使bar成为参考,并且不更改程序的语义或使其成为UB

如果您使bar接受左值引用,则它不能接受临时值:

struct X {};

auto bar(X& x) -> decltype(x)
{
    return x;
}

auto test()
{
    bar(X{});
}
<source>:12:5: error: no matching function for call to 'bar'

    bar(X{});

    ^~~

<source>:4:6: note: candidate function not viable: expects an l-value for 1st argument

auto bar(X& x) -> decltype(x)

     ^

1 error generated.

如果您将其作为r值引用,则无法进行进一步修改就不能返回它:

struct X {};

auto bar(X&& x) -> decltype(x)
{
    return x;
}

auto test()
{
    bar(X{});
}
<source>:6:12: error: rvalue reference to type 'X' cannot bind to lvalue of type 'X'

    return x;

           ^

1 error generated.

好的,您可以通过移动参数来解决此特定问题。但这远远超出了您最初打算更改的范围。不过,为了论证,我们假设您已经这样做,或者说原始程序已经在这样做了:

#include <utility>

struct X { };

auto bar(X&& x) -> decltype(x)
{
    return std::move(x);
}

auto test()
{
    bar(X{});
}

这终于可以编译了。但是您看到问题了吗?您返回对过期对象的引用,并返回悬挂的引用:

// before

#include <utility>

struct X { auto foo() const {} };

auto bar(X x) -> decltype(x) // bar returns a prvalue
{
    return x;
    // or
    // return std::move(x); // redundant, but valid and equivalent
}

auto test()
{
    const X& xr = bar(X{}); // xr prolongs the lifetime of the temporary returned by `bar`

    xr.foo(); // OK, no problem
}
// after

#include <utility>

struct X { auto foo() const {} };

auto bar(X&& x) -> decltype(x) // now bar returns an xvalue
{
    return std::move(x);
}

auto test()
{
    const X& xr = bar(X{}); // xr cannot prolong the life of an xvalue
    // the temporary objects created as part of calling `bar` is now expired
    // and xr references it
    // any attempt to use xr results in UB

    xr.foo(); // Undefined Behaviour
}

没有办法做你想做的事。

程序员,负担就在您身上:如果您需要值,请编写值,如果您需要引用,请编写引用。就这么简单。

答案 1 :(得分:2)

否。

我还没有听说过任何具有此功能的编译器。

相关问题