![](/img/trans.png)
[英]Validation of an std::initializer_list in constexpr context
[英]constexpr array and std::initializer_list
我試圖編寫一個可以像這樣使用的編譯時valarray:
constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };
static_assert(a[0] == 1.0, "");
static_assert(a[3] == 4.3, "");
static_assert(a.size() == 6, "");
我設法用以下實現來做它並且它工作正常(使用GCC 4.7):
#include <initializer_list>
template<typename T>
struct array
{
private:
const std::size_t _size;
const T* _data;
public:
constexpr array(std::initializer_list<T> values):
_size(values.size()),
_data(values.begin())
{}
constexpr auto operator[](std::size_t n)
-> T
{
return _data[n]
}
constexpr auto size() const
-> std::size_t;
{
return _size;
}
};
雖然它對我來說很好,但我不確定std::initializer_list
的行為,可能會使用一些未定義的行為。
constexpr
for std::initializer_list
構造函數, begin
和size
都很好,即使它嚴格來說不是C ++ 11,因為N3471最近被采用並使其符合標准。
關於未定義的行為,我不確定std::initializer_list
的底層數組是否存在,或者是否存在,是否有一個意思是讓它比只有array's
構造函數更長壽。 你怎么看?
編輯:我可能不太清楚,但我真的不關心實際的陣列。 我真正感興趣的是std::initializer_list
及其在編譯時的底層數組的行為。
您當前的代碼不應該根據當前的C ++ 11規則進行編譯 。 使用clang 3.2編譯時,我收到以下錯誤:
source.cpp:33:28: error: constexpr variable 'a' must be initialized by a constant
expression
constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
這是因為std::initializer_list
s ctors和成員函數的begin
和end
都沒有標記為constexpr
。 但是, 已經提出了改變這一點的建議 。 順便說一句,libstdc ++已經將這些標記為constexpr
。
現在下一個問題是std::initializer_list
的底層數組的生命周期 。 這在8.5.4p6中解釋:
該數組與任何其他臨時對象(12.2)具有相同的生命周期,除了從數組初始化initializer_list對象擴展了數組的生命周期,就像綁定對臨時對象的引用一樣。
這意味着底層數組與values
對象具有相同的生命周期,並在array
構造函數退出時終止。 因此, _data
指向過期的內存, _data[n]
是未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.