標準は5.3.4[expr.new]/7
新しい(size、value)Type [0]によって返されるポインタは正当なものであり、配列を作成するために使用できますか?
で言う直接新しい宣言内の式の値がゼロである場合、割り当て機能はない要素を持つ配列を割り当てるために呼び出されます。
ゼロサイズの要求が未定義であるとして3.7.3.1[basic.stc.dynamic.allocation]/2
にポインタをデリファレンスの効果が返されます。
しかし、割り当て関数がユーザ定義で、有効なポインタを返したとわかっていれば、逆参照するための未定義の動作ですか?標準では、ユーザーコードの未定義の動作を強制できますか?
私が尋ねる理由は、非デフォルト構成可能型のオブジェクトの動的配列を初期化するもう一つの無意味な試みです。 delete[]
の明白な欠如に加えて、それにはどのような問題があり、それは[0]
でしか呼び出せないのでしょうか? aligned_storage
も正しく使用しましたか?
#include <type_traits>
#include <stdexcept>
#include <memory>
#include <iostream>
struct T {
int val;
T() = delete;
T(int i) : val(i) {}
void* operator new[](std::size_t, std::size_t cnt, const T& t)
{
typedef std::aligned_storage<sizeof(t),
std::alignment_of<T>::value>::type buf;
T* ptr = reinterpret_cast<T*>(new buf[cnt]);
std::uninitialized_fill_n(ptr, cnt, t);
return ptr;
}
};
int main()
{
T* a = new(100, T(7)) T[0]; // using zero is legal per 5.3.4/7
std::cout << "a[0] = " << a[0].val << '\n' // but is this legal?
<< "a[1] = " << a[1].val << '\n'
<< "a[98] = " << a[98].val << '\n'
<< "a[99] = " << a[99].val << '\n';
delete[] a; // free the 100 aligned_storages
}
テスト実行:と予想通りhttp://ideone.com/iBW0z
もキャストがあるときreinterpret_cast
の結果の使用の唯一の非未定義の動作があるMSVC++ 2010 EE
:-) ...今の良い探しています"なぜ' std :: vector'で十分ではないのですか?それはまさにこれを可能にします。 – ildjarn
@ildjarn:それだけで十分です。私は言語の境界を探っています。 – Cubbi
十分に公正な: - ] – ildjarn