标识为函数的向量构造函数
Vector constructor identified as function
考虑这段代码:
#include <iostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <string>
int main() {
std::istringstream ss("abcabc abc a b e");
std::vector<std::string> words(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>());
std::string deciphered;
int shift = 5;
for (size_t i = 0; i < shift; i++)
{
for (size_t j = 0; i + j < words.size(); j += shift)
{
deciphered += words[i + j];
}
}
}
基本上,我想拆分单词并将它们存储到我的 words
数组中。但是我得到编译错误:
main.cpp: In function 'int main()':
main.cpp:14:40: error: request for member 'size' in 'words', which is of non-class type 'std::vector<std::__cxx11::basic_string<char> >(std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> > (*)())'
14 | for (size_t j = 0; i + j < words.size(); j += shift)
| ^~~~
main.cpp:16:33: warning: pointer to a function used in arithmetic [-Wpointer-arith]
16 | deciphered += words[i + j];
| ^
main.cpp:16:33: error: invalid conversion from 'std::vector<std::__cxx11::basic_string<char> > (*)(std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> > (*)())' to 'char' [-fpermissive]
16 | deciphered += words[i + j];
| ~~~~~~~~~~~^
| |
| std::vector<std::__cxx11::basic_string<char> > (*)(std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> > (*)())
In file included from c:\mingw\lib\gcc\mingw32.2.0\include\c++\string:55,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\locale_classes.h:40,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\ios_base.h:41,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\ios:42,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\ostream:38,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\iostream:39,
from main.cpp:1:
c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\basic_string.h:1186:25: note: initializing argument 1 of 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator+=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
1186 | operator+=(_CharT __c)
| ~~~~~~~^~~
根据错误判断,我的变量 words
被识别为一个函数。
我很困惑,这种行为的原因是什么?我该如何解决?
这就是所谓的 most vexing parse,在这种情况下,您应该使用大括号初始化语法,这会让编译器知道您正在尝试构造 class 的实例,而不是声明一个函数。
即 std::vector<int> a{}
而不是 std::vector<int> a()
根据C++语言的规则,在这一行中:
std::vector<std::string> words(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>());
这是一个新标识符的声明 words
,如您所愿。但是,其他一切都出乎意料:
words
是一个函数,返回 std::vector<std::string>
并接受两个 std::istream_iterator<std::string>
类型的参数。第一个参数命名为 ss
,第二个参数未命名。
在多个 C++ 版本中,有多种方法可以强制编译器将此视为变量的声明和初始化。最简单的是在 C++11 中添加的,@Moshe 建议:使用大括号而不是圆括号来指定初始化器。
std::vector<std::string> words{std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>()};
考虑这段代码:
#include <iostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <string>
int main() {
std::istringstream ss("abcabc abc a b e");
std::vector<std::string> words(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>());
std::string deciphered;
int shift = 5;
for (size_t i = 0; i < shift; i++)
{
for (size_t j = 0; i + j < words.size(); j += shift)
{
deciphered += words[i + j];
}
}
}
基本上,我想拆分单词并将它们存储到我的 words
数组中。但是我得到编译错误:
main.cpp: In function 'int main()':
main.cpp:14:40: error: request for member 'size' in 'words', which is of non-class type 'std::vector<std::__cxx11::basic_string<char> >(std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> > (*)())'
14 | for (size_t j = 0; i + j < words.size(); j += shift)
| ^~~~
main.cpp:16:33: warning: pointer to a function used in arithmetic [-Wpointer-arith]
16 | deciphered += words[i + j];
| ^
main.cpp:16:33: error: invalid conversion from 'std::vector<std::__cxx11::basic_string<char> > (*)(std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> > (*)())' to 'char' [-fpermissive]
16 | deciphered += words[i + j];
| ~~~~~~~~~~~^
| |
| std::vector<std::__cxx11::basic_string<char> > (*)(std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> > (*)())
In file included from c:\mingw\lib\gcc\mingw32.2.0\include\c++\string:55,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\locale_classes.h:40,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\ios_base.h:41,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\ios:42,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\ostream:38,
from c:\mingw\lib\gcc\mingw32.2.0\include\c++\iostream:39,
from main.cpp:1:
c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\basic_string.h:1186:25: note: initializing argument 1 of 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator+=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
1186 | operator+=(_CharT __c)
| ~~~~~~~^~~
根据错误判断,我的变量 words
被识别为一个函数。
我很困惑,这种行为的原因是什么?我该如何解决?
这就是所谓的 most vexing parse,在这种情况下,您应该使用大括号初始化语法,这会让编译器知道您正在尝试构造 class 的实例,而不是声明一个函数。
即 std::vector<int> a{}
而不是 std::vector<int> a()
根据C++语言的规则,在这一行中:
std::vector<std::string> words(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>());
这是一个新标识符的声明 words
,如您所愿。但是,其他一切都出乎意料:
words
是一个函数,返回 std::vector<std::string>
并接受两个 std::istream_iterator<std::string>
类型的参数。第一个参数命名为 ss
,第二个参数未命名。
在多个 C++ 版本中,有多种方法可以强制编译器将此视为变量的声明和初始化。最简单的是在 C++11 中添加的,@Moshe 建议:使用大括号而不是圆括号来指定初始化器。
std::vector<std::string> words{std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>()};