私はペアの配列を持っています。私は0、1または-1を作るためにこの配列のmemsetを使いたい。どうしたらいいですか?私たちはいつものように通常の手順ですか?memset C++でペアの配列
ペアと配列は次のとおりです。
std::pair<int, int> ar[100][100];
私はペアの配列を持っています。私は0、1または-1を作るためにこの配列のmemsetを使いたい。どうしたらいいですか?私たちはいつものように通常の手順ですか?memset C++でペアの配列
ペアと配列は次のとおりです。
std::pair<int, int> ar[100][100];
(std::pair
ではありません)PODタイプではないものにmemset
を使用しないでください - 行うには、未定義の動作です(うまくいかないだろうそう)。
コンストラクタを持つクラスでは、これらのコンストラクタを呼び出す必要があります。memset
はそうしません。 POD
データメンバーを持たないクラスには、 - memset
というメンバのコンストラクタが必要です。
小さいアレイの場合は、代わりにaggregate initializationを使用できます。 大きな配列の場合は、ループを使用できます。 また、std::fillもあります。
また、コンパイル時にサイズがわかっている場合は、Cスタイルの配列に対してstd::arrayを使用することをお勧めします。そうでない場合は、std::vectorです。
'std :: pair'は型でもありません。しかし、 'std :: pait
@juanchopanza - 引用http://en.cppreference.com/w/cpp/string/byte/memset "オブジェクトがトリビュアコピー可能でない場合(スカラー、配列、またはC互換構造体など)、ビヘイビア定義されていません。 'std :: pair'は簡単にはコピーできません。 –
前述のように、ペアはPODではありません。
#include <tuple>
#include <utility>
#include <cstring>
/* this is a POD */
using pair_matrix = int [100][100][2];
extern std::tuple<int, int> foo();
extern void bar(std::tuple<int&, int&>);
int main()
{
pair_matrix m;
/* we can memset PODS */
std::memset(std::addressof(m), sizeof(m), 0);
/* we can convert the 2-d array into a tuple easily */
auto at = [&m](int x, int y) {
auto& a = m[y][x];
return std::tie(a[0], a[1]);
};
/* and manipulate as a tuple */
at(10,10) = foo();
bar(at(10,10));
}
別の(おそらくよりロバストな)方法は、fill
方法を有する多次元配列クラスの概念を発明することである:データは、ユーティリティの少ない損失でPODとして再構築することができるしかし
:
#include <tuple>
#include <utility>
#include <memory>
template<class Type, std::size_t...Dimensions> struct dimension_view;
template<class Type> struct dimension_view<Type>
{
static constexpr std::size_t extent = 1;
static constexpr std::size_t size() { return extent; }
static constexpr std::size_t storage_size = 1;
using storage_type = Type;
constexpr dimension_view(Type* data) : data_(data) {}
operator Type&() { return *data_; }
template<class Other>
constexpr Type& operator=(Other&& other) {
*data_ = std::forward<Other>(other);
return *data_;
}
storage_type* data_;
};
template<class Type, std::size_t Dim, std::size_t...Rest>
struct dimension_view<Type, Dim, Rest...>
{
using next = dimension_view<Type, Rest...>;
static constexpr std::size_t extent = Dim;
static constexpr std::size_t size() { return extent; }
static constexpr std::size_t storage_size = Dim * next::storage_size;
using storage_type = Type [storage_size];
constexpr dimension_view(Type* data) : data_(data) {}
auto begin() -> Type*
{
return data_;
}
auto end() -> Type*
{
return std::addressof(data_[extent * next::storage_size]);
}
auto operator[](std::size_t i) {
return next(std::addressof(data_[i * next::storage_size]));
}
Type* data_ ;
};
template<class T, std::size_t...Dims>
struct multi_dimensional_array
{
using view_type = dimension_view<T, Dims...>;
using storage_type = typename view_type::storage_type;
template<class...Args, std::enable_if_t<std::is_nothrow_constructible<T, Args...>::value>* = nullptr>
constexpr multi_dimensional_array(Args&&...args)
{
for(auto&& store : data_)
{
new (std::addressof(store)) T (args...);
}
}
template<class...Args, std::enable_if_t<not std::is_nothrow_constructible<T, Args...>::value>* = nullptr>
multi_dimensional_array(Args&&...args)
{
auto count = std::size_t(0);
try {
for(auto&& store : data_)
{
new (std::addressof(store)) T (args...);
++count;
}
}
catch(...) {
destroy(count);
}
}
/* delete copies for now */
multi_dimensional_array(multi_dimensional_array const&) = delete;
multi_dimensional_array& operator=(multi_dimensional_array const&) = delete;
multi_dimensional_array(multi_dimensional_array &&) = delete;
multi_dimensional_array& operator=(multi_dimensional_array &&) = delete;
~multi_dimensional_array()
{
destroy(view_type::storage_size);
}
void destroy(std::size_t last)
{
while(last--) {
reinterpret_cast<T*>(get_data()+last)->~T(); }
}
constexpr auto begin_storage() {
return view_type(get_data()).begin();
}
constexpr auto end_storage() {
return view_type(get_data()).end();
}
constexpr auto fill(T value) -> void
{
std::fill(begin_storage(), end_storage(), value);
}
constexpr auto operator[](std::size_t i) -> decltype(auto) {
return view_type(get_data())[i];
}
constexpr T* get_data() {
return reinterpret_cast<T*>(data_);
}
std::aligned_storage_t<sizeof(T), alignof(T)> data_[view_type::storage_size];
};
using pair_matrix = multi_dimensional_array<std::pair<int, int>, 100, 100>;
void force_view(pair_matrix&);
void force_deref(std::pair<int, int>&);
std::size_t getval();
int main()
{
/* create with initial values */
pair_matrix m(std::make_pair(-1, 1));
/* fill the entire multidimentional array */
m.fill(std::make_pair(-1, -1));
m[10][10] = std::make_pair(1,1);
/* force compiler to generate some code to exercise implementation */
force_view(m);
force_deref(m[getval()][getval()]);
}
C++の方法は、memset
の代わりにstd::fill
を使用することで、何かのように:
std::pair<int, int> ar[100][100];
std::fill(&ar[0][0], &ar[0][0] + 100 * 100, std::make_pair(-1, -1));
あなたはC++で何かをmemsetすることはほとんどありません。イニシャライザを使用してください。 –
あなたはペアの配列の配列を持っています。だから、あなたは、すべてのもの、またはペアの配列をmemsetしたいですか? – juanchopanza
私たちがいつもしているように、これを1にする方法は? – melpomene