2017-11-11 76 views
0

我有這樣一段代碼:某種生成循環

template<class T, class color_type> 
void assign_channels(T* ptr, const color_type& color) { 
    *(ptr + 0) = get_channel<0>(color); 

    if constexpr(1 < color_type::size) { 
     *(ptr + 1) = get_channel<1>(color); 
    } 
    if constexpr(2 < color_type::size) { 
     *(ptr + 2) = get_channel<2>(color); 
    } 
    if constexpr(3 < color_type::size) { 
     *(ptr + 3) = get_channel<3>(color); 
    } 
    if constexpr(4 < color_type::size) { 
     *(ptr + 4) = get_channel<4>(color); 
    } 
    if constexpr(5 < color_type::size) { 
     *(ptr + 5) = get_channel<5>(color); 
    } 
    if constexpr(6 < color_type::size) { 
     *(ptr + 6) = get_channel<6>(color); 
    } 
    if constexpr(7 < color_type::size) { 
     *(ptr + 7) = get_channel<7>(color); 
    } 
} 

它有兩個明顯的缺陷:

  1. ,除非我有不超過8個通道將無法正常工作;
  2. 它主要是樣板。

有沒有一種方式在C++中重寫它在某種類型的循環?我認爲一個反覆出現的模板結構可以完成這項工作,但它不是很可讀。我該怎麼辦?

+1

爲什麼'get_channel'是一個模板? o.0' – Alexander

+0

@Alexander這是一個長期以來運行時間最小化的真正靈活的'color_t'。 :| –

+0

表達'*(ptr + 5)'的更常見的方式是'ptr [5]'。 – nwp

回答

4

使用摺疊表達式和std::index_sequence在C++ 17

template<class T, class color_type, size_t... Is> 
void assign_channels(T* ptr, const color_type& color, std::index_sequence<Is...>) { 
    ((ptr[Is] = get_channel<Is>(color)), ...); 
} 

template<class T, class color_type> 
void assign_channels(T* ptr, const color_type& color) { 
    assign_channels(ptr, color, std::make_index_sequence<color_type::size>{}); 
} 

此前C++ 17,你必須重寫倍的表達作爲遞歸。