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

How to initialize auto-type array of multiple types objects

我需要用 tuple 的参数初始化一个数组。所以我试着这样设置:

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

但我收到以下错误:

‘pixels’ declared as array of ‘auto’ auto pixels[] = {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;
}

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

#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)...};

}