简体   繁体   English

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

[英]C++ compiler, force pass by reference

Is it possible to set as default a C++ compiler to interpret all parameter passing as being by-reference defining a new modifier to specify that you need a passage by copy.是否可以将 C++ 编译器设置为默认值,以将所有参数传递解释为通过引用定义新修饰符以指定您需要通过复制传递。

Programming I found that only rerely I need to pass data by copy so, at least for me, would be much more effective to have "reference by default"编程我发现只需要通过副本传递数据,因此,至少对我而言,“默认引用”会更有效

Not only there isn't such a feature, there can never be one .不仅没有这样的功能,而且永远不可能有 Doing so would make well-defined programs ill-formed or worst, having Undefined Behaviour.这样做会使定义良好的程序格式错误或最糟糕,具有未定义的行为。

Consider this simple well-formed program:考虑这个简单的格式良好的程序:

struct X {};

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

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

How would you transform it?你会如何改造它? There is no way to make bar take reference and not change the semantics of the program or make it UB没有办法让bar引用而不改变程序的语义或使其成为 UB

If you make bar take l-value reference then it can't accept a temporary:如果您让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.

If you make it take an r-value reference then you cannot return it without further modifications:如果你让它接受一个右值引用,那么你不能在没有进一步修改的情况下返回它:

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.

Ok, you can solve this particular problem by moving the parameter.好的,您可以通过移动参数来解决这个特定问题。 But that is well beyond what you initially set to change.但这远远超出了您最初设定的更改范围。 Nevertheless, for the sake of the argument let's say you do, or that the original program was already doing it:尽管如此,为了论证,假设您这样做了,或者原始程序已经这样做了:

#include <utility>

struct X { };

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

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

This finally indeed compiles.这终于确实编译了。 But do you see the problem?但是你看到问题了吗? You return a reference to an expired object, you return a dangling reference:您返回对过期 object 的引用,您返回一个悬空引用:

// 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
}

There is no way to do what you want to do.没有办法做你想做的事。

The burden is on you, the programmer: if you need values write values, if you need references write references.程序员的负担在你身上:如果你需要值就写值,如果你需要引用就写引用。 It's as simple as that.就这么简单。

No.不。

I haven't heard of any compiler having this feature.我还没有听说过任何编译器具有此功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM