gpt4 book ai didi

c++ - C++中的函数与变量声明

转载 作者:IT老高 更新时间:2023-10-28 23:17:12 27 4
gpt4 key购买 nike

此代码有效:

std::ifstream f(mapFilename.c_str());
std::string s = std::string(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());
ParseGameState(s);

其中 mapFilenamestd::stringvoid ParseGameState(const std::string&);

这不是:

std::ifstream f(mapFilename.c_str());
std::string s(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());
ParseGameState(s);

这是错误:

game.cpp: In member function ‘int Game::LoadMapFromFile(const std::string&)’:
game.cpp:423: error: no matching function for call to ‘ParseGameState(std::string (&)(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> > (*)()))’
game.cpp:363: note: candidates are: ParseGameState(const std::string&)

所以在这种情况下,它似乎将 s 识别为函数声明而不是变量声明。

这是为什么呢?这是 GCC 4.2.1(Apple 构建)中的错误吗?或者 GCC 是否正确处理了这个问题?这在 C++ 标准中是否未定义?

最佳答案

这是 C++ 的“最令人头疼的解析”。一个快速的谷歌应该会出现很多带有很多细节的点击。基本答案是,是的,编译器 将其视为函数声明——而 C++ 要求它这样做。你的编译器没有问题(至少在这方面)。

如果有任何安慰的话,你有很多好伙伴遇到这个问题。事实上,C++0x 添加新的大括号初始化语法是很常见的,很大程度上是因为它避免了这种歧义。使用它,您可以编写如下内容:

std::string s{std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>()};

这将清楚地表明,大括号的内容是用于初始化 s 的值,不是 类型的参数到名为 s< 的函数。我不知道 Apple 是否有它的移植版,但 gcc 接受 4.5 版(左右)的新语法。

编辑:重读 N3092,约翰内斯(像往常一样)非常正确。适用的语言是(第 8.5.4/3/5 节):“如果 T 具有初始化器列表构造函数,则参数列表由初始化器列表作为单个参数组成;否则,参数列表由初始化器的元素组成列表。”

因此,由于 std::string 有一个初始化列表构造函数,这将尝试将两个 istreambuf_iterator 填充到初始化列表中,并将其传递到带有初始化列表的 std::string ctor——但这将是类型不匹配,因此代码无法编译。对于其他一些类型类型(与 std::string 不同,not 具有初始化列表 ctor),上面的转换将起作用(感谢“否则...”在上面的报价中)。对于 std::string,您必须使用当前的替代方法之一,例如 std::string s = std:string(...) .

对于错误的建议修复,我深表歉意——在这种情况下,更糟糕的是,因为它混淆了一个本身可能会过度混淆的问题,如果有任何问题需要仔细澄清,尤其是在接下来的几年中.

关于c++ - C++中的函数与变量声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3695411/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com