簡體   English   中英

constexpr if 和返回值優化

[英]constexpr if and the return value optimization

我有這個代碼:

#include <string>

class A {
 public:
//    A(A const &) = delete;   // Code fails if this is uncommented.
    explicit A(int);
    explicit A(::std::string const &);

 private:
    ::std::string myname_;
    int foo_;
};

static constexpr bool which = false;

A test(::std::string const &s, int a)
{
    if constexpr (which) {
        A x{a};
        return x;
    } else {
        A y{s};
        return y;
    }
}

如果A具有已刪除的復制構造函數,則此代碼將失敗。 但是,鑒於其中包含if constexpr函數的返回類型規則,編譯器似乎應該在這里應用 RVO。

除了在語言規范中被忽視的情況之外,是否有其他原因?

這與if constexpr無關

簡單地說,這段代碼是不允許編譯的:

class A {
 public:
    A(A const &) = delete;
    explicit A(int);
};

A test(int a)
{
    A x{a};
    return x; // <-- error call to a deleted constructor `A(A const &) = delete;`
}

您正在考慮的 C++17 中的更改與臨時物化有關,不適用於 NRVO,因為x不是純右值。

例如,這段代碼在 C++17 之前是非法的,現在是允許的:

A test(int a)
{
    return A{a}; // legal since C++17
}

這是NRVO ,這是非強制性復制省略:

(強調我的)

  • return 語句中,當操作數是具有自動存儲期的非易失性對象的名稱時,該對象不是函數參數或 catch 子句參數,並且屬於相同的類類型(忽略cv 限定)作為函數返回類型。 這種復制省略的變體被稱為 NRVO,“命名返回值優化”。

這是一種優化:即使它發生並且復制/ move (since C++11)構造函數沒有被調用,它仍然必須存在且可訪問(好像根本沒有發生優化),否則程序是病態的形成


順便說一句:請注意,在您的代碼中,將檢查constexpr if語句的if部分和else部分。

在模板之外,完全檢查丟棄的語句。 如果 constexpr 不能替代#if預處理指令:

 void f() { if constexpr(false) { int i = 0; int *p = i; // Error even though in discarded statement } }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM