用户定义的字面量添加到C ++中的新功能是什么? [英] What new capabilities do user-defined literals add to C++?

查看:101
本文介绍了用户定义的字面量添加到C ++中的新功能是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 11 引入了用户定义文字,它将允许基于现有文字引入新的文字语法( int hex string float

  //虚数
std :: complex< long double>运算符_i(long double d)// cooked form
{
return std :: complex< long double>(0,d)
}
auto val = 3.14_i; // val = complex< long double>(0,3.14)

//二进制值
int operator_B(const char *); // raw form
int answer = 101010_B; // answer = 42

// std :: string
std :: string operator_s(const char * str,size_t / * length * /)
{
return std :: string(str);
}

auto hi =hello_s +world; // + works,hello_s是一个不是指针的字符串

// units
assert(1_kg == 2.2_lb); //给或取0.00462262磅

乍一看这看起来很酷,但我想知道如何适用它真的是,当我试图想到有后缀 _AD _BC 创建日期我发现,到操作员订单。 1974/01 / 06_AD 将首先评估 1974/01 (as plain int s),后来只有 06_AD (8月和9月没有必要写入 0 八进制)。这可以通过使语法 1974-1 / 6_AD 来解决,以便运算符评估顺序工作,但它是笨重的。



所以我的问题是这个,你觉得这个功能会证明自己是正确的吗?您想要定义哪些其他文字,以使您的C ++代码更具可读性?






更新语法以适合最终草稿2011年6月

解决方案

以下是使用用户定义文字而不是构造函数调用的优势: p>

  #include< bitset> 
#include< iostream>

template< char ... Bits>
struct checkbits
{
static const bool valid = false;
};

template< char High,char ... Bits>
struct checkbits< High,Bits ...>
{
static const bool valid =(High =='0'|| High =='1')
&& checkbits< Bits ...> :: valid;
};

template< char High>
struct checkbits< High>
{
static const bool valid =(High =='0'|| High =='1');
};

template< char ... Bits>
inline constexpr std :: bitset< sizeof ...(Bits)>
operator_bits()noexcept
{
static_assert(checkbits< Bits ...> :: valid,binary digit in binary string);
return std :: bitset< sizeof ...(Bits)>((char []){Bits ...,'\0'});
}

int
main()
{
自动位= 010101010101010101010101010101010101010101010101010101010101010101_bits;
std :: cout<<位<< std :: endl;
std :: cout<< size =< bits.size()< std :: endl;
std :: cout<< count =< bits.count()< std :: endl;
std :: cout<< value =< bits.to_ullong()<< std :: endl;

//这在编译时触发static_assert。
auto badbits = 2101010101010101010101010101010101010101010101010101010101010101_bits;

//这在运行时抛出。
std :: bitset< 64> badbits2(21010101010101010101010101010101010101010101010101010101010101010101010101010101_bits);
}

优点是运行时异常转换为编译时错误。
你不能添加静态assert到bitset ctor接受一个字符串(至少不是没有字符串模板参数)。


C++11 introduces user-defined literals which will allow the introduction of new literal syntax based on existing literals (int, hex, string, float) so that any type will be able to have a literal presentation.

Examples:

// imaginary numbers
std::complex<long double> operator "" _i(long double d) // cooked form
{ 
    return std::complex<long double>(0, d); 
}
auto val = 3.14_i; // val = complex<long double>(0, 3.14)

// binary values
int operator "" _B(const char*); // raw form
int answer = 101010_B; // answer = 42

// std::string
std::string operator "" _s(const char* str, size_t /*length*/) 
{ 
    return std::string(str); 
}

auto hi = "hello"_s + " world"; // + works, "hello"_s is a string not a pointer

// units
assert(1_kg == 2.2_lb); // give or take 0.00462262 pounds

At first glance this looks very cool but I'm wondering how applicable it really is, when I tried to think of having the suffixes _AD and _BC create dates I found that it's problematic due to operator order. 1974/01/06_AD would first evaluate 1974/01 (as plain ints) and only later the 06_AD (to say nothing of August and September having to be written without the 0 for octal reasons). This can be worked around by having the syntax be 1974-1/6_AD so that the operator evaluation order works but it's clunky.

So what my question boils down to is this, do you feel this feature will justify itself? What other literals would you like to define that will make your C++ code more readable?


Updated syntax to fit the final draft on June 2011

解决方案

Here's a case where there is an advantage to using user-defined literals instead of a constructor call:

#include <bitset>
#include <iostream>

template<char... Bits>
  struct checkbits
  {
    static const bool valid = false;
  };

template<char High, char... Bits>
  struct checkbits<High, Bits...>
  {
    static const bool valid = (High == '0' || High == '1')
                   && checkbits<Bits...>::valid;
  };

template<char High>
  struct checkbits<High>
  {
    static const bool valid = (High == '0' || High == '1');
  };

template<char... Bits>
  inline constexpr std::bitset<sizeof...(Bits)>
  operator"" _bits() noexcept
  {
    static_assert(checkbits<Bits...>::valid, "invalid digit in binary string");
    return std::bitset<sizeof...(Bits)>((char []){Bits..., '\0'});
  }

int
main()
{
  auto bits = 0101010101010101010101010101010101010101010101010101010101010101_bits;
  std::cout << bits << std::endl;
  std::cout << "size = " << bits.size() << std::endl;
  std::cout << "count = " << bits.count() << std::endl;
  std::cout << "value = " << bits.to_ullong() << std::endl;

  //  This triggers the static_assert at compile time.
  auto badbits = 2101010101010101010101010101010101010101010101010101010101010101_bits;

  //  This throws at run time.
  std::bitset<64> badbits2("2101010101010101010101010101010101010101010101010101010101010101_bits");
}

The advantage is that a run-time exception is converted to a compile-time error. You couldn't add the static assert to the bitset ctor taking a string (at least not without string template arguments).

这篇关于用户定义的字面量添加到C ++中的新功能是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆