[英]Can't initialize constexpr value from return value of constexpr function
[英]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.