简体   繁体   English

从std :: istreambuf_iterator创建std :: string,奇怪的语法怪癖

[英]Create std::string from std::istreambuf_iterator, strange syntax quirk

I found somewhere the following idiom for reading a file into a string: 我发现以下习惯用于将文件读入字符串:

std::ifstream file("path/to/some/file.ext");
std::string contents(
    std::istreambuf_iterator<char>(file),
    (std::istreambuf_iterator<char>())
);

Which works just fine as it is. 哪个工作得很好。 However, if I remove the parentheses around the second iterator argument, that is: 但是,如果我删除第二个迭代器参数周围的括号,那就是:

std::string contents(
    std::istreambuf_iterator<char>(file),
    std::istreambuf_iterator<char>()
);

As soon as I try to call any method on the string object, for example: 一旦我尝试在字符串对象上调用任何方法,例如:

const char *buffer = contents.c_str();

I get a compile error of the form: 我收到表单的编译错误:

error: request for member 'c_str' in 'contents', which is of non-class type 'std::string(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)()) {aka std::basic_string<char>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)())}'

Also if I try to assign that string to another: 此外,如果我尝试将该字符串分配给另一个:

std::string contents2 = contents;

I get an error of the form: 我收到表单错误:

error: conversion from 'std::string(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)()) {aka std::basic_string<char>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)())}' to non-scalar type 'std::string {aka std::basic_string<char>}' requested

Why is this? 为什么是这样? I can see no reason for those parentheses being needed, much less affect the type definition of the contents variable. 我看不出需要这些括号的原因,更不用说影响contents变量的类型定义了。 I am using g++ 4.8.2. 我正在使用g ++ 4.8.2。

That is an example of Most Vexing Parse : 这是Most Vexing Parse的一个例子:

std::string contents(
    std::istreambuf_iterator<char>(file),
    std::istreambuf_iterator<char>()
);

The statement is parsed as the declaration of a function named contents that takes two parameters. 该语句被解析为带有两个参数的名为contents的函数的声明。 One parameter that is a variable named file of type std::istreambuf_iterator , and a second one that is a function that takes no arguments and returns an std::istreambuf_iterator . 一个参数是一个名为std::istreambuf_iterator类型的file的变量,另一个参数是一个不带参数的函数并返回一个std::istreambuf_iterator Specification of function parameter names are optional. 功能参数名称的规范是可选的。

Wrapping at least one of the expressions in parenthesis causes it to be parsed as a variable definition. 在括号中包含至少一个表达式会使其被解析为变量定义。

C++11 solves this problem with its provision of uniform-initialization : C ++ 11通过提供统一初始化解决了这个问题:

std::string contents{std::istreambuf_iterator<char>{file}, {}};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从std :: istreambuf_iterator &lt;&gt;复制到std :: vector &lt;&gt; - copying from a std::istreambuf_iterator<> to a std::vector<> 如何使用 std::istreambuf_iterator 初始化字符串 - How to use std::istreambuf_iterator to intialize a string 传递一个std :: vector <char> 从istreambuf_iterator构造 - Passing a std::vector<char> constructed from istreambuf_iterator 对“std::istreambuf_iterator”的使用感到困惑 - Confused about usage of 'std::istreambuf_iterator' 对`std :: istreambuf_iterator`的使用感到困惑 - Confused about usage of `std::istreambuf_iterator` std :: istreambuf_iterator <char> 没有参数初始化? - std::istreambuf_iterator<char> initializes with no arguments? 从std :: istreambuf_iterator和std :: ifstream获取所需的二进制数据范围 - Getting desired binary data ranges from std::istreambuf_iterator and std::ifstream 为什么是`std::istreambuf_iterator<char> ` 在构造字符串时视为函数声明? - why is `std::istreambuf_iterator<char>` regard as function declaration when constrcuting a string? istreambuf_iterator与结构 - istreambuf_iterator with structs C ++如何将ifstream内容(从文件)分配给带偏移量的字符串(istreambuf_iterator) - C++ How to assign ifstream content (from file) to string with offset (istreambuf_iterator)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM