【C++】使用自定义字面量,少写几句代码

发布时间:2024年01月18日

目录

1.字面量?

2.拓展字面量

3.定义自己的字面量

1.格式要求

2.参数要求

3.参数具体说明

4.举例说明


以下代码在wn10 cygwin gcc 11.4中调试通过?

1.字面量?

? ? ? ? 字面量是编程语言中的一个术语,指的是直接出现在代码中的数据值,而不是变量或表达式。字面量可以是数字、字符串、布尔值、数组、对象等。比如,在C++中

1,2,3
"aa"
3.14
0X2A
052

这些都是。在编写代码时,字面量是直接用来使用据,而无需定义变量或使用表达式。

2.拓展字面量

?比如说,想定义一些新的字面量,来满足一些需求的话,如下例

char * a = "bbbbb";
string k = "aaa"+a;

想把两个char*连接成为一个string ,以上代码就不行,得如下操作

char * a = "bbbbb";
string k = string{"aaa"}+a;

这就没有问题了

但是,其实还有更简单的方式,就是利用stl提供的字面量运算符,上例子改为

char * a = "bbbbb";
string k = "aaa"s+a;

这个也对,只是把string{"aaa"}改为了“aaa”s,在字符串后面加了一个s,这样,"aaa"就变成了string类型,就可以进行字符串的连接操作了

“aaa”s,这种行为,就是自定义字面量。只不过这个s是stl库中提供的。

3.定义自己的字面量

上例使用起来就比较简单,但是,标准库提供的可能也无法满足我们所有需求,还是要自己去定义字面量

类似s那些的字面量定义,自己实现上并不复杂,举个简单例子,定义一个和s相同功能的字面量,叫_MS

string operator "" _MS(const char* a,size_t count){
    return string{a};
}
int main()
{  
    char * a = "bbbbb";
    string k = "aaa"_MS+a;
    cout<<k<<endl;
    return 1;
}

没报错,能编译,运行结果正常

其实,一看operator就明白了,他就是个重载运算符的操作.只不过重载定义字面量是有一定格式和要求的

1.格式要求

虽然像s这样的方式很简洁,但是自定义的格式,不能是这样的,自己定义的字面量必须要以一个下划线_,作为开头,两个下划线不行

ReturnValue operator "" _XXX(参数){
    return ReturnValue;
}

_XXX就是自定义的字面量,returnvalue就是返回值,参数就是使用的时候_XXX前面的那个字面量,比如测试一下_MS

string operator "" _MS(const char* a,size_t count){
    cout<<a<<";"<<count<<endl;
    return string{a};
}
int main()
{  
    string k = "aaa"_MS;
    return 1;
}

输出?

aaa;3

2.参数要求

这个参数,实际是有要求的。先看个例子

string operator "" _BB(const char *a){
    return string{a};
}

string operator "" _AA(char a){
    return string{a};
}
int main()
{  
    string k = 1_AA;
    string g = 1_BB;
    return 1;
}

上面

string k = 1_AA;

这句子是有错误的,clang的提示

No matching literal operator for call to 'operator""_AA' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template ?clang(ovl_no_viable_literal_operator)

说明参数类型是错误的,实际上,参数类型,只能是以下这些类型

( const char* )
( unsigned long long int )
( long double )
( char )
( wchar_t )
( char8_t )
( char16_t )
( char32_t )
( const char*, std::size_t )
( const wchar_t*, std::size_t )
( const char8_t*, std::size_t )
( const char16_t*, std::size_t )
( const char32_t*, std::size_t )

不仅参数有要求,使用时也是有要求,比如

string operator "" _BB(const char *a){
    return string{a};
}

string operator "" _AA(char a){
    return string{a};
}

这两个定义是没有问题的,但是使用时候是有问题,char a的使用的时候,前面必须是个字符

string k = '1'_AA;

这样就对了,同样,如果

string g = '1'_BB;

这样也是错的,因为,使用const char *a参数的前面是要数字才行

3.参数具体说明

括号内是参数类型

( const char* ):前面是整数和浮点数据
( unsigned long long int ):前面是整数,他的级别高于( const char* )
( long double ):前面是浮点,他的级别高于( const char* )
( char ):前面是字符
( wchar_t ):前面是字符
( char8_t ):前面是字符
( char16_t ):前面是字符
( char32_t ):前面是字符
( const char*, std::size_t ):前面是字符串,sizet,是前面的长度
( const wchar_t*, std::size_t ):前面是字符串,sizet,是前面的长度
( const char8_t*, std::size_t ):前面是字符串,sizet,是前面的长度
( const char16_t*, std::size_t ):前面是字符串,sizet,是前面的长度
( const char32_t*, std::size_t ):前面是字符串,sizet,是前面的长度

?4.举例说明

把上面的挑几个类型,举例说明

string operator "" _AA(const char* a)
{
    cout<<"const char* a"<<endl;
    return string{a}; 
}

string operator "" _AA(unsigned long long int a)
{  
    cout<<"unsigned long long int a"<<endl;
    return to_string(a);
}

string operator "" _AA(long double a){
     cout<<"long double a"<<endl;
    return to_string(a);
}

string operator "" _AA(char a){
    cout<<"char a"<<endl;
    return string{a}; 
}

string operator "" _AA( const char* a, std::size_t ){
    cout<<"const char* a, std::size_t"<<endl;
    return string{a}; 
}

int main()
{ 
    string s1 = 2_AA;
    string s2 = 3.1_AA;
    string s3 = 'a'_AA;
    string s4 = "a"_AA;
    return 1;
}

输出

unsigned long long int a
long double a
char a
const char* a, std::size_t

后两个好理解,s1,s2分别调用了第二个和第三个AAA,这就是在上面参数说明中说的,他俩的优先级更高,虽然第一个AAA可以传入整数和浮点数,但第二个和第三个优先级更高,所以优先调用后两个

文章来源:https://blog.csdn.net/weixin_44305576/article/details/134813657
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。