如何定义运算符,以便可以将用户定义类型的数组转换为基元类型的数组

How can I define operators so that a array of user-defined types can be transformed into an array of primitive types?

本文关键字:定义 类型 数组 用户 转换 何定义 运算符      更新时间:2023-10-16

我给出以下代码来说明我的问题:

#include <vector>
struct Complex
{
     int a, b, c;
     Complex() : a(3), b(4), c(10) {}
     operator int() const {  return a+b+c; }
};
int main()
{
   Complex abc;
   int value = (abc);
   Complex def;
   def.a = 20;
   int value2 = (def);
   std::vector<Complex> ar;
   ar.push_back(abc);
   ar.push_back(def);
   std::vector<int> ar2;
   ar2.push_back(abc);
   ar2.push_back(def);
   std::vector<int> ar3;
   ar3 = (ar);
}

由于表达式ar3 = (ar),这不会编译。我已经声明了一个转换运算符,以便 Complex 类可以在预期int的地方使用。 我还可以让它用于将Complex对象数组分配给int数组吗?

我试图为 Complex 数组声明一个非成员转换运算符,但这是不允许的:

void std::vector<int> operator = (std::vector<Complex> complexArray)
{
    std::vector<int> abc;
    for(int i=0; i<complexArray.size(); i++)
     abc.push_back(complexArray[i]);
    return abc;
}

你可以考虑std::vector的范围构造函数。

std::vector<int> ar3(begin(ar), end(ar));

每当你想要转换某些东西时,std::transform函数可能很好用。

在您的情况下,您可以执行以下操作

// Create the new vector with the same size as the complex vector
std::vector<int> abc(complexArray.size());
std::transform(std::begin(complexVector), std::end(complexVector),
               std::begin(abc),
               [](Complex const& complex)
               {
                   int result;
                   // Code here that converts the complex structure to an integer
                   // and stores the integer in the variable result
                   return result;
               });

在上面的std::transform调用之后(一旦您使用代码完成它以实际执行结构转换),向量abc将包含来自源向量complexVectorComplex结构的所有转换整数。

忘记自动隐式转换(至少对于标准库容器)。但是,如果您愿意接受如下例所示的显式转换

 const std::vector<int> vi {1, 2, 3, 4, 5};
 const std::vector<double> vd = container_cast(vi);

然后是container_cast()实用程序的实现。请注意,它不仅可以在不同元素类型的同一模板容器的实例化之间强制转换(即 std::vector<int>std::vector<double> ),但也在不同的容器之间(例如 std::vectorstd::list)。

#include <iostream>
#include <vector>
#include <list>
template<class SourceContainer>
class ContainerConverter
{
    const SourceContainer& s_;
public:
    explicit ContainerConverter(const SourceContainer& s) : s_(s) {}
    template<class TargetContainer>
    operator TargetContainer() const
    {
        return TargetContainer(s_.begin(), s_.end());
    }
};
template<class C>
ContainerConverter<C> container_cast(const C& c)
{
    return ContainerConverter<C>(c);
}
template<class C>
void printContainer(const C& c)
{
    std::cout << "{ ";
    for( auto x : c )
        std::cout << x << ' ';
    std::cout << "}" << std::endl;
}
int main()
{
    const std::vector<double> vd {2.2, 7.7, 5.5, 1.1, -4.4};
    printContainer(vd);
    const std::vector<int> vi = container_cast(vd);
    printContainer(vi);
    const std::list<float> lf = container_cast(vd);
    printContainer(lf);
    return 0;
}