[C++11]字面量s && 可变参数模板

139 阅读2分钟

1.字面量s

s 后缀是一个用于将常规的字符串字面量(const char* 类型)转换为 std::string 类型的后缀。 原理也是比较简单

namespace std {
    inline namespace string_literals {
        // 将 const char* 字面量转换为 std::string
        std::string operator""s(const char* str, size_t length) {
            return std::string(str, length);
        }
    }
}

使用如下:

#include <iostream>
#include <string>
 
void print_with_zeros(auto const note, std::string const& s)
{
    std::cout << note;
    for (const char c : s)
        c ? std::cout << c : std::cout << "0";
    std::cout << " (size = " << s.size() << ")\n";
}
 
int main()
{
    //使用字面量
    using namespace std::string_literals;
 
    std::string s1 = "abc\0\0def";
    std::string s2 = "abc\0\0def"s;
    print_with_zeros("s1: ", s1);
    print_with_zeros("s2: ", s2);
 
}

\0const char* 结束标志,导致s1在内存中只存了abc(这是c语言得规定 C++为了兼容c语言 必须这样)
而在s2中 将const char* 转换为std::string \0就是0(ASCII码值)

结果如下: image.png

2. 可变参数模板

定义得模板可以接受任意数量、任意类型的参数。这样的模板称为可变参数模板。
比如要实现一个简单的函数print,可以输出任意被<< 输出数据。

实现一个可变参数模板,要将第一个参数剥离出来,然后递归调用处理所有剩下的参数。

void print() {} // 处理无参得得情况 什么都不做
//模板函数 ARGS...表示剩余的参数(变长参数包)
template <class T, class... ARGS>
void print(T t, ARGS... args)
{
    std::cout << t << ' '; // 打印当前参数
    print(args...);  // 递归调用,处理剩下的参数
}

使用如下:

#include <iostream>
#include <string>
//s 字面量后缀用于将 const char* 字面量转换为 std::string 
using namespace std::string_literals; // 启用 "s" 字面量后缀


void print() {} // 递归结束条件 一定要有

//模板函数 ARGS...表示剩余的参数(变长参数包)
template <class T, class... ARGS>
void print(T t, ARGS... args)
{
    std::cout << t << ' '; // 打印当前参数
    print(args...);  // 递归调用,处理剩下的参数
}

int main()
{
    print("first: ", 1, 2.2, "hello\n"s);
    print("\nsecond: ", 0.2, 'c', "yuck!"s, 0, 1, 2, '\n');
    return 0;
}

输出如下: (""s)属于C++14语法 所以要指定C++14标准。 image.png