从std :: istreambuf_iterator创建std :: string,奇怪的语法quirk [英] Create std::string from std::istreambuf_iterator, strange syntax quirk

查看:833
本文介绍了从std :: istreambuf_iterator创建std :: string,奇怪的语法quirk的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

它的工作原理很好。但是,如果我删除第二个迭代器参数周围的括号,那就是:

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

一旦我尝试调用字符串对象上的任何方法,例如:

  const char * buffer = contents.c_str(); 

我收到以下形式的编译错误:



错误:在'contents'中请求成员'c_str',它是非类型'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>>(*)())}'



尝试将该字符串分配给另一个:

  std :: string contents2 = contents; 

我收到以下表单的错误:



错误:从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> (*)(*)())}'到非标量类型的'std :: string {aka std :: basic_string< char>}



为什么?我看不到需要这些括号的原因,更少影响 contents 变量的类型定义。我使用的是g ++ 4.8.2。

解决方案

这是大多数Vexing解析

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

语句被解析为 contents 需要两个参数。一个参数是类型为 std :: istreambuf_iterator 的名为文件的变量的变量,第二个参数是一个函数不带参数并返回 std :: istreambuf_iterator



在括号中包含至少一个表达式会将其解析为变量定义。



C ++ 11通过提供 uniform-initialization 解决了这个问题:

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


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. I am using g++ 4.8.2.

解决方案

That is an example of 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. 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. 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:

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

这篇关于从std :: istreambuf_iterator创建std :: string,奇怪的语法quirk的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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