11

C++11ユーザー定義リテラルを提供します。私はそれらをいじり始めたばかりですが、定義した単一のリテラルにすべてのSI 乗数を自動的に追加できるかどうか疑問に思いました。

たとえば、私が定義した場合

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

whereLengthはいくつかの基本クラスのサブクラスです。を返すすべてのリテラルに対して(ブースト演算子と同じ精神で) SI 乗数を自動的Unitsに追加するメカニズムが必要です。Length

// 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

私が見る限り、おそらくいくつかのマクロ マジックを除けば、すべてのユーザー定義リテラルには明示的な定義が必要なため、これを自動的に行う方法はありません。

..または私は何かを見落としていますか?

4

2 に答える 2

3

「奇妙なマクロ」なしで、あなたが求めていることを正確に行う方法はないと思います。これは私が得ることができる限りです:

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");
}
于 2013-03-04T08:38:57.070 に答える
-1

operator "" _m(const char *)フロートを自分で解析する意思がある限り、フレーバーを使用できませんか? 1234k_mこれにより、浮動小数点値の一般的な SI 対応パーサーを呼び出して書き込むことが可能になります。

于 2013-03-04T08:05:37.473 に答える