4

この質問はこのために尋ねられています。

C ++ 11では、数値リテラルに対して次のようなリテラルを定義できます。

template<char...> OutputType operator "" _suffix();

つまり503_suffix<'5','0','3'>

これは素晴らしいですが、それが入っている形ではあまり役に立ちません。

これを数値タイプに戻すにはどうすればよいですか?これはに変わり<'5','0','3'>ますconstexpr 503。さらに、浮動小数点リテラルでも機能する必要があります。または<'5','.','3>になりますint 5float 5.3

前の質問で部分的な解決策が見つかりましたが、整数以外では機能しません。

template <typename t>
constexpr t pow(t base, int exp) {
  return (exp > 0) ? base * pow(base, exp-1) : 1;
};

template <char...> struct literal;
template <> struct literal<> {
  static const unsigned int to_int = 0;
};
template <char c, char ...cv> struct literal<c, cv...> {
  static const unsigned int to_int = (c - '0') * pow(10, sizeof...(cv)) + literal<cv...>::to_int;
};
// use: literal<...>::to_int
// literal<'1','.','5'>::to_int doesn't work
// literal<'1','.','5'>::to_float not implemented
4

2 に答える 2

4

アールワールには簡単な方法があります。非型パラメーターパックは、次のように初期化子リストに展開できます。

#include <iostream>

template<char... Chars>
  double
  operator "" _suffix()
  {
    const char str[]{Chars..., '\0'};
    return atof(str);
  }

int
main()
{
  std::cout << 123.456789_suffix << std::endl;
}
于 2011-11-13T05:37:11.690 に答える
3

以下は、指数部分のないフロートで機能するはずだと思います(テストされていません):

template<bool fp, long long num, long long denom, char ...> struct literal;

template<bool fp, long long num, long long denom> struct literal<fp, num, denom>
{
   static constexpr double value() { return (1.0*num)/denom; }
};

template<long long num, long long denom, char digit, char... rest>
  struct literal<false, num, denom, digit, rest...>
{
  static constexpr double value()
  {
    return literal<false, 10*num + (digit-'0'), denom, rest...>::value();
  }
};

template<long long num, long long denom, char digit, char... rest>
  struct literal<true, num, denom, digit, rest...>
{
  static constexpr double value()
  {
    return literal<true, 10*num + (digit-'0'), 10*denom, rest...>::value();
  }
};

template<long long num, long long denom, char... rest>
  struct literal<false, num, denom, '.', rest...>
{
  static constexpr double value()
  {
    return literal<true, num, denom, rest...>::value();
  }
};

template<char... c> double operator "" _dbl()
{
  return literal<false, 0, 1, c...>::value();
}

これを拡張して指数関数的な部分も取る方法は明らかです。

もちろん、エラーチェックも実行する必要があります(文字が実際に数字であることを確認してください)。

于 2011-11-13T02:12:58.820 に答える