【问题标题】:C++ compiler, force pass by referenceC++ 编译器,强制通过引用传递
【发布时间】:2019-09-23 09:55:04
【问题描述】:

是否可以将 C++ 编译器设置为默认值,以将所有参数传递解释为通过引用定义一个新修饰符来指定您需要通过复制传递。

编程我发现我只需要通过副本传递数据,因此,至少对我来说,“默认引用”会更有效

【问题讨论】:

  • 我不认为这是任何 c++ 编译器中的预定义标志。您可以自己实现它(即作为 clang 编译器传递)。但它可能会破坏许多库,甚至是标准库
  • 不,否则它就不是 C++ 编译器。
  • gcc 中没有这样的功能或标志。我不确定其他编译器,但没有编译器会实现这一点。它可能会造成混乱和可读性问题。
  • 哦,伙计,你也是通过引用传递整数吗?这太疯狂了。
  • 你可以只使用像 Qt 这样的框架及其所有类型。它们大部分是写时复制。或者您可以编写自己的 CoW 类型。这似乎比尝试更改语言要好得多。即使改用 Java 或 C# 似乎也是解决这个“问题”的更明智的“解决方案”。

标签: c++ reference parameter-passing default


【解决方案1】:

不仅没有这样的功能,永远不可能有。这样做会使定义良好的程序格式错误或最糟糕,具有未定义的行为。

考虑这个简单的格式良好的程序:

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.

如果你让它接受一个右值引用,那么你不能在没有进一步修改的情况下返回它:

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
}

没有办法做你想做的事。

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

【讨论】:

    【解决方案2】:

    没有。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 2011-01-17
      • 2020-04-01
      相关资源
      最近更新 更多