如何初始化多个类型对象的自动类型数组

时间:2018-12-21 02:10:12

标签: c++ arrays auto

我需要使用tuple的参数初始化数组。因此,我尝试将其设置为:

auto average_intensity(Ts&&... args)
{
    auto pixels[] = {args... };
    // [...]
}

但是出现以下错误:

  

“像素”被声明为“自动”自动像素数组[] = {args ...};

我该如何解决?

这是完整的代码:

#include <iostream>
#include <type_traits>
#include <string>
#include <utility>
#include <tuple>


using namespace std;

struct gray_pixel{
  uint8_t gray;
  auto intensity(){
      return gray - 127;  
  }
};


struct rgb_pixel{
  float red, green, blue;
  auto intensity(){
      return (red - 127 + green -127 + blue - 127) * 255 / 3;  
  }
};


template<typename T>
auto intensity(T pixel){
    return pixel.intensity();
}
//find the average intensity of multiple pixels from different types (gray_pixel or rgb_pixel)
template <typename... Ts>
auto average_intensity(Ts&&... args)
{
    auto pixels[] = {args...};

    auto sum = 0;
    int count = 0;
    for(auto pixel : pixels){
        sum +=intensity(pixel);
        count++;
    }
    return sum/count;
}


int main()
{

    gray_pixel pixel_gray = {255};
    rgb_pixel pixel_rgb = {0,0,250};

    cout << "sizeof(pixel_gray): " << sizeof(pixel_gray) << endl;
    cout << "sizeof(pixel_rgb): " << sizeof(pixel_rgb) << endl;

    cout << "intensity(pixel_gray): " << intensity(pixel_gray) << endl;
    cout << "intensity(pixel_rgb): " << intensity(pixel_rgb) << endl;

    cout << "average_intensity(pixel_gray, pixel_rgb): " << average_intensity(pixel_gray, pixel_rgb) << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:1)

您需要一个元组而不是一个数组。但是,那么您不能使用for循环,而必须使用编译时方法作为下面代码中的fold表达式:

#include <tuple>
#include <iostream>

using namespace std;

struct gray_pixel  {
    uint8_t gray;
    auto intensity() const {
        return gray - 127;
    }
};


struct rgb_pixel{
    float red, green, blue;
    auto intensity() const {
        return (red - 127 + green -127 + blue - 127) * 255 / 3;
    }
};


template<typename T>
auto intensity(const T& pixel){
    return pixel.intensity();
}
//find the average intensity of multiple pixels from different types (gray_pixel or rgb_pixel)
template <typename... Ts>
auto average_intensity(Ts&&... args)
{

    // you actually don't need this here, but I leave it
    // to clarify how to capture the args in a tuple.    
    // you can use std::apply to perform calculations on the elements
    auto tup = std::forward_as_tuple(std::forward<Ts>(args)...);

    const float count = sizeof...(Ts);

    // a lambda that gets the intensity of a single pixel
    auto get_intensity = [](auto&& pix) {
        return static_cast<float>(std::forward<decltype(pix)>(pix).intensity());
    };
    // fold expression to sum all the intensities of the args
    auto sum = (get_intensity(args) + ...);
    return sum/count;
}


int main()
{

    gray_pixel pixel_gray = {255};
    rgb_pixel pixel_rgb = {255,127,127};

    cout << "sizeof(pixel_gray): " << sizeof(pixel_gray) << endl;
    cout << "sizeof(pixel_rgb): " << sizeof(pixel_rgb) << endl;

    cout << "intensity(pixel_gray): " << intensity(pixel_gray) << endl;
    cout << "intensity(pixel_rgb): " << intensity(pixel_rgb) << endl;

    cout << "average_intensity(pixel_gray, pixel_rgb): " << average_intensity(pixel_gray, pixel_rgb) << endl;
    return 0;
}

这是原始问题的答案:

您可以这样尝试:

如果所有Ts都属于同一类型,则可以删除std::common_type并改用第一个元素的类型。 另外,我建议使用std::array而不是C样式的数组。

#include <utility>
#include <array>

template<typename... Ts>
auto average_intensity(Ts&&... ts) {

    using Auto = std::common_type_t <std::decay_t<Ts>...>;

    std::array<Auto, sizeof...(Ts)> pixels {std::forward<Ts>(ts)...};

    // or if you really want an C-style array
    Auto pixels[]{std::forward<Ts>(ts)...};

}