是否可以在C++中创建"attributed"类型?

Can I create "attributed" types in C++?

本文关键字:attributed 类型 创建 C++ 是否      更新时间:2023-10-16

当我说"attribute"时,我指的是类似于std:array<int, 5> arr的东西。5是数组的一个属性。

这里有一个激励的例子:假设我想创建一个包含格式化信息的数字或字符串。所以我可能想写Double<7,2> foo,意思是我想要foo是双精度,当我打印它的时候,它的宽度是7,精度是2。我可以用通常的方式分配任务:

foo = 42;
double bar = foo;

有办法做到这一点吗?

你可能会问我为什么要这样做。例如,为什么不在构造函数中定义一个接受width和precision参数的类呢?答案是,我不认为你可以在结构中使用它们。例如,我希望能够这样做:

struct Account {
    std::string description;
    Double<7, 2> amount;
    Double<7, 2> balance;
    Double<9, 3> percent;
};

您可以使用非类型模板参数和double隐式转换编写自己的包装器类。优点是该类的大小保持不变。

#include <iostream>
template<std::streamsize WIDTH, std::streamsize PRECISION>
struct DoubleEx
{
    double value;
    DoubleEx(double fValue) : value(fValue) {}
    operator double() const { return value; }
    friend std::ostream& operator << (std::ostream& stream, const DoubleEx &val)
    {
        stream.width(WIDTH);
        auto oldPrecision = stream.precision();
        stream.precision(PRECISION);
        stream << val.value;
        stream.precision(oldPrecision);
        return stream;
    }
};
int main()
{
    DoubleEx<15, 8> num1 = 123.45678;
    double num2 = num1;
    auto num3 = num1;

    std::cout << "num1 = " << num1 << "  size=" << sizeof(num1) << std::endl;
    std::cout << "num2 = " << num2 << "  size=" << sizeof(num2) << std::endl;
    std::cout << "num3 = " << num3 << "  size=" << sizeof(num3) << std::endl;
}
输出:

num1 =       123.45678  size=8
num2 = 123.457  size=8
num3 =       123.45678  size=8

我不确定我明白你的意思,但也许mixins可以帮助你。
作为一个最小的工作示例:

#include <cstddef>
#include <string>
template<std::size_t N, std::size_t M>
struct Double {
    operator double() { return N*M; }
};
struct Description {
    std::string description;
};
template<typename ...T>
struct Mock: T... { };
using Account = Mock<Double<7, 2>, Description>;
int main() {
    Account account;
    account.description = "foo";
    double d = account;
}