Simpler way to set multiple array slots to one value

前端 未结 10 2244
我寻月下人不归
我寻月下人不归 2021-02-18 16:31

I\'m coding in C++, and I have the following code:

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

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


        
相关标签:
10条回答
  • 2021-02-18 16:46

    A variant of aaronman's answer:

    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;
    }
    

    Example: Click here

    0 讨论(0)
  • 2021-02-18 16:48
    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 << ' ';
    
    
    }
    
    0 讨论(0)
  • 2021-02-18 16:53

    Any fancy trickery you do will be unrolled by the compiler/assembler into exactly what you have. Are you doing this for readability reasons? If your array is already init, you can do:

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

    But I stress my point above; it will be transformed into exactly what you have.

    0 讨论(0)
  • 2021-02-18 16:59

    This function will help make it less painful.

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

    Call it like this.

    initialize(array,{9,5,14},2);
    
    0 讨论(0)
  • 2021-02-18 17:00

    Just for the fun of it I created a somewhat different approach which needs a bit of infrastructure allowing initialization like so:

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

    If the digits need to be separated by commas, there is a small change needed. In any case, here is the complete code:

    #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";
    }
    
    0 讨论(0)
  • 2021-02-18 17:02

    Use overload operator << .

    #include <iostream>
    #include <iomanip>
    #include <cmath>
    
    // value and indexes wrapper
    template< typename T,  std::size_t ... Ints> struct _s{ T value; };
    
    //deduced value type
    template< std::size_t ... Ints,  typename T>
    constexpr inline   _s<T, Ints... >  _ ( T const& v )noexcept { return {v}; }
    
    
    // stored array reference
    template< typename T, std::size_t N>
    struct _ref
    {
        using array_ref = T (&)[N];
    
        array_ref ref;
    };
    
    
    //join _s and _ref with << operator.
    template< 
            template< typename , std::size_t ... > class IC, 
            typename U, std::size_t N, std::size_t ... indexes
            >
    constexpr _ref<U,N> operator << (_ref<U,N> r, IC<U, indexes...> ic ) noexcept
    {
        using list = bool[];
        return (  (void)list{ false, (  (void)(r.ref[indexes] = ic.value), false) ... }) , r ;
    
        //return r;
    }
    
    
    //helper function, for creating _ref<T,N> from array.
    template< typename T, std::size_t N>
    constexpr inline _ref<T,N> _i(T (&array)[N] ) noexcept { return {array}; }
    
    
    
    int main()
    {
    
       int a[15] = {0};
    
       _i(a) << _<0,3,4,5>(7) << _<8,9, 14>( 6 ) ;
    
    
       for(auto x : a)std::cout << x << "  " ;  
       //       0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
      //result: 7  0  0  7  7  7  0  0  6  6  0  0  0  0  6
    
    
      double b[101]{0};
    
      _i(b) << _<0,10,20,30,40,50,60,70,80,90>(3.14) 
            << _<11,21,22,23,24,25>(2.71) 
            << _<5,15,25,45,95>(1.414) ;
    }
    
    0 讨论(0)
提交回复
热议问题