c++ - 如何根据单个用户定义的文字自动添加文字定义?

标签 c++ c++11 operator-overloading user-defined-literals

C++11 提供 user-defined literals .我刚开始玩弄它们,这让我想知道是否可以自动添加所有 SI multipliers到我定义的单个文字?

例如,如果我定义

Length operator "" _m(long double m) {
    return Length(m); // Length in meters
}

Length 是一些 Units 基类的子类,我希望有一种机制可以自动添加(本着同样的精神作为 boost operators ) 返回 Length 的所有文字的 SI 乘数:

// these are added automatically when defining the literal "_m": 
                                         // Length in:
Length operator "" _Ym(long double Ym);  // Yottameters
Length operator "" _Zm(long double Zm);  // Zetameters
...                                      // ...
...                                      // ...
Length operator "" _km(long double km);  // kilometers
Length operator "" _mm(long double mm);  // millimeters
...                                      // ...       
...                                      // ...
Length operator "" _zm(long double zm);  // zeptometers
Length operator "" _ym(long double ym);  // yoctometers

据我所知,除了一些宏魔法之外,没有办法自动执行此操作,因为所有用户定义的文字都需要一个显式定义。

..还是我忽略了什么?

最佳答案

我不认为有一种方法可以在没有“奇怪的宏”的情况下完全按照您的要求进行操作。这是我所能得到的:

template<typename T, T (*op)(long double)>
struct SI
{
    // ...
    constexpr static T micro = op (.000001);
    constexpr static T milli = op (.001);
    constexpr static T kilo = op (1000);
    constexpr static T mega = op (1000000);
    // ...
};

struct Length
{
    constexpr Length(long double d) : _d(d) { }
    constexpr operator long double() { return _d; }
    long double _d;
};

constexpr Length operator "" _m(long double m) {
    return Length(m);
}

typedef SI<Length, ::operator "" _m> SI_Length;

int main()
{
    constexpr Length l = 3 * SI_Length::kilo;
    static_assert(l == 3000, "error");
}

如果允许奇怪的宏,那么像下面这样的东西应该可以完成这项工作:

#define DEFINE_SI_MULTIPLIERS(T, unit) \
    constexpr T operator "" _u ## unit(long double m) \
    { return ::operator "" _ ## unit(0.000001 * m); } \
    constexpr T operator "" _m ## unit(long double m) \
    { return ::operator "" _ ## unit(0.001 * m); } \
    constexpr T operator "" _k ## unit(long double m) \
    { return ::operator "" _ ## unit(1000 * m); } \
    // ...

DEFINE_SI_MULTIPLIERS(Length, m)

int main()
{
    constexpr Length l = 3.0_km;
    static_assert(l == 3000, "error");
}

关于c++ - 如何根据单个用户定义的文字自动添加文字定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15196955/

相关文章:

c++ - 为什么代码行即使从未运行也会出错?

c++ - 可以将容器的复制构造函数定义为不可复制值类型的删除吗?

c++ - 使用 lambda 和宏进行错误处理有缺点吗?

c++ - 成员右值引用和对象生命周期

c++ - 如何在 C++ 中执行 Y = aX + Y

c++ - 覆盖数组索引运算符

c++ - C++中new的使用

c++ - 用于自追加的字符串反向迭代器的持久性

c++ - 将时间戳打印到 ostream 的最简单方法

c++ - 如何重载operator []以索引自定义 vector 类的shared_ptr元素?