21

私はC++でコーディングしており、次のコードがあります。

int array[30];
array[9] = 1;
array[5] = 1;
array[14] = 1;

array[8] = 2;
array[15] = 2;
array[23] = 2;
array[12] = 2;
//...

次のような配列を初期化する方法はありますか?

int array[30];
array[9,5,14] = 1;
array[8,15,23,12] = 2;
//...

注: 実際のコードでは、1 つの値に設定する必要がある最大 30 個のスロットが存在する可能性があります。

4

10 に答える 10

32

この機能により、痛みが軽減されます。

void initialize(int * arr, std::initializer_list<std::size_t> list, int value) {
    for (auto i : list) {
        arr[i] = value;
    }
}

このように呼びます。

initialize(array,{9,5,14},2);
于 2013-10-04T00:45:00.807 に答える
9

アーロンマンの答えの変形:

template <typename T>
void initialize(T array[], const T& value)
{
}

template <size_t index, size_t... indices, typename T>
void initialize(T array[], const T& value)
{
    array[index] = value;
    initialize<indices...>(array, value);
}

int main()
{
    int array[10];

    initialize<0,3,6>(array, 99);

    std::cout << array[0] << " " << array[3] << " " << array[6] << std::endl;
}

例:ここをクリック

于 2013-10-04T01:11:03.000 に答える
7

楽しみのために、次のような初期化を可能にする少しのインフラストラクチャを必要とする、多少異なるアプローチを作成しました。

double array[40] = {};
"9 5 14"_idx(array) = 1;
"8 15 23 12"_idx(array) = 2;

数字をコンマで区切る必要がある場合は、小さな変更が必要です。いずれにせよ、完全なコードは次のとおりです。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <iterator>

template <int Size, typename T = int>
class assign
{
    int  d_indices[Size];
    int* d_end;
    T*   d_array;
    void operator=(assign const&) = delete;
public:
    assign(char const* base, std::size_t n)
        : d_end(std::copy(std::istream_iterator<int>(
                      std::istringstream(std::string(base, n)) >> std::skipws),
                          std::istream_iterator<int>(), this->d_indices))
        , d_array()
    {
    }
    assign(assign<Size>* as, T* a)
        : d_end(std::copy(as->begin(), as->end(), this->d_indices))
        , d_array(a) {
    }
    assign(assign const& o)
        : d_end(std::copy(o.begin(), o.end(), this->d_indices))
        , d_array(o.d_array)
    {
    }
    int const* begin() const { return this->d_indices; }
    int const* end() const   { return this->d_end; }
    template <typename A>
    assign<Size, A> operator()(A* array) {
        return assign<Size, A>(this, array);
    }
    void operator=(T const& value) {
        for (auto it(this->begin()), end(this->end()); it != end; ++it) {
            d_array[*it] = value;
        }
    }
};

assign<30> operator""_idx(char const* base, std::size_t n)
{
    return assign<30>(base, n);
}

int main()
{
    double array[40] = {};
    "1 3 5"_idx(array) = 17;
    "4 18 7"_idx(array) = 19;
    std::copy(std::begin(array), std::end(array),
              std::ostream_iterator<double>(std::cout, " "));
    std::cout << "\n";
}
于 2013-10-04T01:19:40.027 に答える
2

可変引数テンプレート引数ユニバーサル初期化リストをまだサポートしていないコンパイラは、投稿されたソリューションの一部が機能しないことに気付くのが面倒な場合があります

どうやら、OPは数値の配列のみを扱うことを意図しておりvalarray可変引数を使用すると、実際にはこの問題を非常に簡単に解決できます。

#include <valarray>     
#include <cstdarg>
#include <iostream>
#include <algorithm>
#include <iterator>
template <std::size_t size >
std::valarray<std::size_t>  selection( ... )
{
    va_list arguments; 
    std::valarray<std::size_t> sel(size);   
    //Skip the first element
    va_start ( arguments, size );
    va_arg ( arguments, int );
    for(auto &elem : sel)
        elem = va_arg ( arguments, int );
    va_end ( arguments );
    return sel;

}
int main ()
{
    //Create an array of 30 integers
    std::valarray<int> array(30);
    //The first argument is the count of indexes
    //followed by the indexes of the array to initialize
    array[selection<3>(9,5,14)] = 1;
    array[selection<4>(8,15,13, 12)] = 2;
    std::copy(std::begin(array), std::end(array),
              std::ostream_iterator<int>(std::cout, " "));
    return 0;
}
于 2013-10-04T07:00:46.083 に答える
2

インデックスが関連していない場合にできる最善の方法は、割り当てを「チェーン」することです。

array[9] = array[5] = array[14] = 1;

ただし、決定論的な方法でインデックスを計算する方法がある場合は、ループを使用できます。

for (size_t i = 0; i < 3; ++i)
    array[transform_into_index(i)] = 1;

この最後の例は、インデックスが保存されているコンテナがある場合にも当てはまります。したがって、次のようなことができます。

const std::vector<size_t> indexes = { 9, 5, 14 };
for (auto i: indexes)
    array[i] = 1;
于 2013-10-04T00:42:25.210 に答える
1
struct _i_t
{
    int * array;


    struct s
    {
        int* array;
        std::initializer_list<int> l;

        s const&   operator = (int value) const noexcept
        {
            for(auto i : l )
              array[i] = value;

            return *this;
        }
    };

    s operator []( std::initializer_list<int> i ) const noexcept
    {
        return s{array, i};
    }
};

template< std::size_t N>
constexpr _i_t   _i( int(&array)[N]) noexcept { return {array}; }

int main()
{
  int a[15] = {0};
  _i(a)[{1,3,5,7,9}] =  7;

  for(auto x : a)std::cout << x << ' ';


}
于 2013-10-04T14:16:26.037 に答える
1

静的初期化には、次のような構文が存在することを覚えています。

int array[30] = {
  [9] = 1, [8] = 2
}

等々。これはgccで機能しますが、別のコンパイラについてはわかりません。

于 2013-10-04T00:43:37.770 に答える
0

あなたが行う手の込んだトリックは、コンパイラ/アセンブラによって展開され、まさにあなたが持っているものになります。読みやすさのためにこれを行っていますか?配列がすでに初期化されている場合は、次のことができます。

array[8] = array[15] = array[23] = array[12] = 2;

しかし、私は上記の点を強調します。それはまさにあなたが持っているものに変換されます。

于 2013-10-04T00:44:44.883 に答える