std::quoted试用学习

发布时间 2023-06-28 20:06:52作者: xiarunliang
std::quoted 是干啥用的,有啥作用?
看是c++14和17中加入的。

quoted 这个单词似乎在计算机里面就有着特殊的意思,可惜没记住。英文原版资料看的少。

 

 

在cppreference网站中的示例如下:(https://en.cppreference.com/w/cpp/io/manip/quoted

void default_delimiter() {
  const std::string in = "std::quoted() quotes this string and embedded \"quotes\" too";
  std::stringstream ss;
  ss << std::quoted(in);
  std::string out;
  ss >> std::quoted(out);

  std::cout << "Default delimiter case:\n"
    "read in     [" << in << "]\n"
    "stored as   [" << ss.str() << "]\n"
    "written out [" << out << "]\n\n";
}

 运行结果:

Default delimiter case:
read in     [std::quoted() quotes this string and embedded "quotes" too]
stored as   ["std::quoted() quotes this string and embedded \"quotes\" too"]
written out [std::quoted() quotes this string and embedded "quotes" too]

  

 看出了什么呢?感觉不够清晰,为啥这示例要经过stringstream折腾下呢,不纯粹了,改改吧:

 

void default_delimiter() {
  const std::string in = "std::quoted() quotes this string and embedded \"quotes\" too";

  auto r1 = std::quoted(in);
  std::string out{"a string a \\,b \",c \\\""};
  auto r2 = std::quoted(out);

  std::cout << "Default delimiter case:\n"
    "read in     [" << in << "]\n"
   // "stored as   [" << ss.str() << "]\n"
    "written out [" << out << "]\n\n";
}

运行结果:

Default delimiter case:
read in     [std::quoted() quotes this string and embedded "quotes" too]
written out [a string a \,b ",c \"]

  

 

改的过程中,遇到第一个问题,这是个函数还是个函数对象或所谓的“可调用体”,看会cppreference网站中的原型是这样的:

template< class CharT >
/*unspecified*/ quoted( const CharT* s,
                        CharT delim = CharT('"'), CharT escape = CharT('\\') );

看着是函数,那,真正关心的函数返回值类型又是啥,那注释的英文单词是“未指定”的意思吧(词典查的)。呃好吧,在vs中转到微软版本的实现看下:

template <class _Elem, class _Traits, class _Alloc>
_NODISCARD _Quote_out<_Elem, _Traits, typename basic_string<_Elem, _Traits, _Alloc>::size_type> quoted(
    const basic_string<_Elem, _Traits, _Alloc>& _Str, _Elem _Delim = _Elem('"'), _Elem _Escape = _Elem('\\')) {
    using _Qobj = _Quote_out<_Elem, _Traits, typename basic_string<_Elem, _Traits, _Alloc>::size_type>;
    return _Qobj(_Str.c_str(), _Str.size(), _Delim, _Escape);
}

它这版本返回的应该是 “_Quote_out<_Elem, _Traits, typename basic_string<_Elem, _Traits, _Alloc>::size_type>”这个模板类型的对象。_Quote_out模板类再瞅眼:

template <class _Elem, class _Traits, class _Sizet>
struct _Quote_out { // store pointer/length for string
    _Quote_out(const _Elem* _Ptr_obj, _Sizet _Size_obj, _Elem _Delim_obj, _Elem _Escape_obj)
        : _Ptr(_Ptr_obj), _Size(_Size_obj), _Delim(_Delim_obj), _Escape(_Escape_obj) {}

    const _Elem* _Ptr; // pointer to string
    _Sizet _Size; // length of string
    _Elem _Delim; // delimiter element
    _Elem _Escape; // escape element

    _Quote_out& operator=(const _Quote_out&) = delete;
};

看着还不是太大。也没用太新的技术,凑合能看懂。

三个模板形参,一个构造函数,四个属性,删除了下赋值操作符(呃,没有删除拷贝构造函数)。

主要功能是啥?构造函数的执行过程也就几个赋值。得看周边了。(追的有点烦了)

在iomanip文件中能看到的有意义的也就一个重载的 <<操作符(作用是将_Quote_out类型对象数据写入流中)。

 是的,只有<<操作符的重载,那示例代码中的 >>对 std::quoted返回值的作用呢,是的quoted在vs这个实现中有几个重载,具体来说,在iomanip文件中看到了四个(其中一个是#if _HAS_CXX17中的),这也是和cppreference网站中的是一致的。

四个重载主要都是参数一的变化,然后再vs的实现中,返回值,有三个是返回的_Quote_out对象,一个返回的是_Quote_in模板对象。而_Quote_in类同时重载了<<和 >>操作符。

 所以对于语句”ss >> std::quoted(out);“,是有过一个_Quote_in临时对象(经std::quoted函数构造并和out这个string对象关联),这个临时对象,从ss流中接收了数据,其实是存储操作到了关联的out这string对象上了。

out做为 quoted函数的第一个参数,在函数体中传给了_Quote_in的构造函数的第一个形参,构造函数中收到这个实参,存给了类的_Str属性(是个引用),在重载的>>操作符中取其引用,对其操作,所以最终还是操作的quoted函数的实参那个对象。

 

 目前,从源码看,quoted函数,返回的类型是个对象,这个对象并没什么实际作用,只是能和 basic_ostream和 basic_istream 进行交互反应。具体功能也体现在对应的两个操作符重载里。

可能能用的常见也就那几个流了,输入、输出流、字符串流、文件流。

 

 

 

 它的作用是什么呢,用于什么场景呢